Package Ganga :: Package Utility :: Package external :: Package ARDAMDClient :: Module diskutils
[hide private]
[frames] | no frames]

Source Code for Module Ganga.Utility.external.ARDAMDClient.diskutils

  1  ################################################################################ 
  2  # Ganga Project. http://cern.ch/ganga 
  3  # 
  4  # $Id: diskutils.py,v 1.1 2008-07-17 16:41:02 moscicki Exp $ 
  5  ################################################################################ 
  6  import sys 
  7  import os 
  8  import types 
  9  import time 
 10  import errno 
 11  import atexit 
 12  import random 
 13   
 14   
 15  ##if time.time() < time.time(): 
 16  ##    timestampMethod = time.time 
 17  ##elif time.clock() < time.clock(): 
 18  ##    timestampMethod = time.clock 
 19  ##else: 
 20  ##    raise OSError("Can not find an appropriate timestamp function in the time module") 
 21   
 22   
 23  #--------------------------------------------------------------------------- 
24 -def timestampMethod():
25 timestamp = '%.7f' % time.time() 26 for p in range(3): 27 timestamp += str(random.randint(0,9)) 28 return timestamp
29 30
31 -def newGuid(value = None):
32 """newGUID(value = None) --> guid value - any python object""" 33 tt = time.gmtime()[0:6] + (random.randint(0,9), 34 random.randint(0,9), 35 random.randint(0,9), 36 random.randint(0,9), 37 random.randint(0,9), 38 random.randint(0,9), 39 random.randint(0,9), 40 random.randint(0,9), 41 random.randint(0,9), 42 id(value)) 43 return '_' + (''.join(map(str, tt))).replace('-','')
44 45
46 -def createLock(lockfile, guid, tries_limit = 200):
47 tries = 0 48 while True: 49 tries = tries +1 50 try: 51 guid += '\0' #mark the end of string 52 fd = os.open(lockfile, os.O_WRONLY | os.O_CREAT | os.O_EXCL) 53 try: 54 guidlen = os.write(fd, guid) 55 finally: 56 os.close(fd) 57 fd = os.open(lockfile, os.O_RDONLY) 58 try: 59 f_guid = os.read(fd, guidlen) 60 finally: 61 os.close(fd) 62 if f_guid != guid: 63 raise OSError("Guids mismatch in the lock file") 64 except OSError, e: 65 if tries > tries_limit: 66 return False 67 time.sleep(0.05) 68 else: 69 return True
70 71
72 -def removeLock(lockfile):
73 try: 74 os.remove(lockfile) 75 except OSError, e: 76 if e[0] != errno.ENOENT: 77 return False 78 return True
79 80 81
82 -class RLock(object):
83 - def __init__(self, lockfile = 'Lock', tries_limit = 200):
84 self.lockfile = lockfile 85 self.guid = newGuid(self) 86 self.counter = 0 87 self.tries_limit = tries_limit 88 atexit.register(self.remove)
89
90 - def acquire(self):
91 if self.counter == 0: 92 if not createLock(self.lockfile, self.guid, self.tries_limit): 93 return False 94 self.counter += 1 95 return True
96
97 - def release(self):
98 if self.counter > 0: 99 if self.counter == 1: 100 if not removeLock(self.lockfile): 101 return 102 self.counter -= 1
103
104 - def remove(self):
105 if self.counter == 0: 106 try: 107 f = file(self.lockfile, 'r') 108 try: 109 f_guid = f.read() 110 finally: 111 f.close() 112 except: 113 return 114 if f_guid.endswith('\0'): #lock file was correctly written 115 if f_guid.rstrip('\0') != self.guid: # by another RLock 116 return 117 removeLock(self.lockfile) 118 self.counter = 0
119 120
121 -class Filterer(object):
122 - def __init__(self, fn, tmp = False):
123 self.fn = fn 124 self.tmp = tmp
125 - def __call__(self, fn):
126 ff = fn.split('_') 127 fflen = len(ff) 128 if fflen > 1: 129 if ff[0] == self.fn: 130 if self.tmp: 131 if fflen == 3: 132 if ff[2] == '': 133 return True 134 else: 135 if fflen == 2: 136 if ff[1] != '': 137 return True 138 return False
139 140
141 -def listFiles(dirname):
142 files = [] 143 for e in os.listdir(dirname): 144 if os.path.isfile(os.path.join(dirname, e)): 145 files.append(e) 146 return files
147 148
149 -def getTimeStamp(fn):
150 # fn -- precise 151 fn = os.path.basename(fn) 152 ff = fn.split('_') 153 if len(ff) > 1: 154 return ff[1].split('.') 155 return (0,0)
156 157
158 -def sorter(x, y):
159 x, y = map(getTimeStamp, (x,y)) 160 if x[0] < y[0]: 161 return -1 162 elif x[0] == y[0]: 163 if x[1] < y[1]: 164 return -1 165 elif x[1] == y[1]: 166 return 0 167 elif x[1] > y[1]: 168 return 1 169 elif x[0] > y[0]: 170 return 1
171 172
173 -def getHistory(fn, tmp = False):
174 # fn -- generic 175 dirname, basename = os.path.split(os.path.abspath(fn)) 176 ffs = filter(Filterer(basename, tmp), listFiles(dirname)) 177 ffs.sort(sorter) 178 return (dirname, ffs)
179 180
181 -def getLast(fn):
182 # fn -- generic 183 dirname, ffs = getHistory(fn) 184 ffs.reverse() 185 for hf in ffs: 186 hfn = os.path.join(dirname, hf) 187 tmp_fn = hfn + '_' 188 if not os.path.isfile(tmp_fn): 189 break 190 else: 191 raise OSError("Can not find file %s" % fn) 192 return hfn
193 194
195 -def __fillEntry(entries, lentr, i, f):
196 # helper function to force garbage collection of temporal lists 197 line = f.readline() 198 line = line.rstrip('\n') 199 if not line: 200 return False 201 fields = line.split('\0') 202 if i < lentr: 203 entries[i] = fields 204 else: 205 entries.append(fields) 206 return True
207 208
209 -def read(fn, entries = None):
210 # fn -- precise 211 # if entries is not none they will be filled first 212 # this is a way to reduce memory leak in Python 213 # function returns list of entries and number of read lines, 214 # which can be less than length of the entries list 215 if entries == None: 216 entries = [] 217 lentr = len(entries) 218 i = 0 219 f = open(fn, 'r') 220 try: 221 while __fillEntry(entries, lentr, i, f): 222 i += 1 223 return (entries, i) 224 finally: 225 f.close()
226 227
228 -def readLast(fn, entries = None):
229 # fn -- generic 230 return read(getLast(fn), entries)[0]
231 232
233 -def move(tmp_fn, fn, tries_limit = 200):
234 # tmp_fn, fn -- precise 235 if os.path.isfile(fn): 236 raise OSError("File exists %s" % fn) 237 os.rename(tmp_fn, fn) 238 # check that file was moved 239 tries = 0 240 while True: 241 tries = tries +1 242 if os.path.isfile(tmp_fn) or not os.path.isfile(fn): 243 if tries > tries_limit: 244 raise OSError("Can not rename file %s" % tmp_fn) 245 time.sleep(0.05) 246 else: 247 return
248 249
250 -def remove(fn, tries_limit = 200):
251 # fn -- generic 252 dirname, ffs = getHistory(fn, tmp = False) 253 for hf in ffs: 254 fn = os.path.join(dirname, hf) 255 os.remove(fn) 256 # check that file was removed 257 tries = 0 258 while True: 259 tries = tries +1 260 if os.path.isfile(fn): 261 if tries > tries_limit: 262 raise OSError("Can not remove file %s" % fn) 263 time.sleep(0.05) 264 else: 265 return
266 267
268 -def write(entries, fn, lines_to_write = -1, tries_limit = 200):
269 # fn -- generic 270 dirname, ffs = getHistory(fn, tmp = False) 271 dirname, hfs = getHistory(fn, tmp = True) 272 fn = '_'.join([fn, timestampMethod()]) 273 tmp_fn = fn + '_' 274 f = open(tmp_fn, 'w') 275 try: 276 for entry in entries: 277 if lines_to_write == 0: 278 break 279 lines_to_write -= 1 280 if not len(entry): 281 continue 282 line='' 283 for field in entry: 284 if len(line): 285 line += '\0' 286 line += str(field) 287 f.write(line + '\n') 288 finally: 289 f.close() 290 move(tmp_fn, fn, tries_limit) 291 for fls in [ffs, hfs]: 292 for hf in fls: 293 hf = os.path.join(dirname, hf) 294 try: 295 os.remove(hf) 296 except OSError: 297 pass 298 return fn
299