Back to index

moin  1.9.0~rc2
Public Member Functions | Public Attributes | Private Member Functions | Private Attributes
MoinMoin.caching.CacheEntry Class Reference

List of all members.

Public Member Functions

def __init__
def exists
def mtime
def size
def uid
def needsUpdate
def lock
def unlock
def open
def read
def write
def close
def update
def content
def remove

Public Attributes

 request
 key
 locking
 use_pickle
 use_encode
 arena_dir

Private Member Functions

def _filename

Private Attributes

 _fname
 _lock
 _fileobj
 _tmp_fname
 _mode

Detailed Description

Definition at line 49 of file caching.py.


Constructor & Destructor Documentation

def MoinMoin.caching.CacheEntry.__init__ (   self,
  request,
  arena,
  key,
  scope = 'wiki',
  do_locking = True,
  use_pickle = False,
  use_encode = False 
)
init a cache entry
    @param request: the request object
    @param arena: either a string or a page object, when we want to use
          page local cache area
    @param key: under which key we access the cache content
    @param scope: the scope where we are caching:
          'item' - an item local cache
          'wiki' - a wiki local cache
          'farm' - a cache for the whole farm
          'dir' - just use some specific directory
    @param do_locking: if there should be a lock, normally True
    @param use_pickle: if data should be pickled/unpickled (nice for arbitrary cache content)
    @param use_encode: if data should be encoded/decoded (nice for readable cache files)

Definition at line 51 of file caching.py.

00051 
00052                  use_pickle=False, use_encode=False):
00053         """ init a cache entry
00054             @param request: the request object
00055             @param arena: either a string or a page object, when we want to use
00056                           page local cache area
00057             @param key: under which key we access the cache content
00058             @param scope: the scope where we are caching:
00059                           'item' - an item local cache
00060                           'wiki' - a wiki local cache
00061                           'farm' - a cache for the whole farm
00062                           'dir' - just use some specific directory
00063             @param do_locking: if there should be a lock, normally True
00064             @param use_pickle: if data should be pickled/unpickled (nice for arbitrary cache content)
00065             @param use_encode: if data should be encoded/decoded (nice for readable cache files)
00066         """
00067         self.request = request
00068         self.key = key
00069         self.locking = do_locking
00070         self.use_pickle = use_pickle
00071         self.use_encode = use_encode
00072         self.arena_dir = get_arena_dir(request, arena, scope)
00073         if not os.path.exists(self.arena_dir):
00074             os.makedirs(self.arena_dir)
00075         self._fname = os.path.join(self.arena_dir, key)
00076 
00077         # used by file-like api:
00078         self._lock = None  # either a read or a write lock
00079         self._fileobj = None  # open cache file object
00080         self._tmp_fname = None  # name of temporary file (used for write)
00081         self._mode = None  # mode of open file object
00082 


Member Function Documentation

def MoinMoin.caching.CacheEntry._filename (   self) [private]

Definition at line 83 of file caching.py.

00083 
00084     def _filename(self):
00085         # DEPRECATED - please use file-like api
00086         return self._fname

Here is the caller graph for this function:

close cache file (and release lock, if any) 

Definition at line 230 of file caching.py.

00230 
00231     def close(self):
00232         """ close cache file (and release lock, if any) """
00233         try:
00234             if self._fileobj:
00235                 self._fileobj.close()
00236                 self._fileobj = None
00237                 if 'w' in self._mode:
00238                     filesys.chmod(self._tmp_fname, 0666 & config.umask) # fix mode that mkstemp chose
00239                     # this is either atomic or happening with real locks set:
00240                     filesys.rename(self._tmp_fname, self._fname)
00241         finally:
00242             if self.locking:
00243                 self.unlock()

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 271 of file caching.py.

00271 
00272     def content(self):
00273         # no file-like api yet, we implement it when we need it
00274         try:
00275             try:
00276                 self.open(mode='r')
00277                 data = self.read()
00278             finally:
00279                 self.close()
00280             if self.use_pickle:
00281                 data = pickle.loads(data)
00282             elif self.use_encode:
00283                 data = data.decode(config.charset)
00284             return data
00285         except (pickle.UnpicklingError, IOError, EOFError, ValueError), err:
00286             raise CacheError(str(err))

Here is the call graph for this function:

Definition at line 87 of file caching.py.

00087 
00088     def exists(self):
00089         return os.path.exists(self._fname)

Here is the caller graph for this function:

def MoinMoin.caching.CacheEntry.lock (   self,
  mode,
  timeout = 10.0 
)
acquire a lock for <mode> ("r" or "w").
we just raise a CacheError if this doesn't work.

Note:
 * .open() calls .lock(), .close() calls .unlock() if do_locking is True.
 * if you need to do a read-modify-write, you want to use a CacheEntry
   with do_locking=False and manually call .lock('w') and .unlock().

Definition at line 134 of file caching.py.

00134 
00135     def lock(self, mode, timeout=10.0):
00136         """
00137         acquire a lock for <mode> ("r" or "w").
00138         we just raise a CacheError if this doesn't work.
00139 
00140         Note:
00141          * .open() calls .lock(), .close() calls .unlock() if do_locking is True.
00142          * if you need to do a read-modify-write, you want to use a CacheEntry
00143            with do_locking=False and manually call .lock('w') and .unlock().
00144         """
00145         lock_dir = os.path.join(self.arena_dir, '__lock__')
00146         if 'r' in mode:
00147             _lock = lock.LazyReadLock(lock_dir, 60.0)
00148         elif 'w' in mode:
00149             _lock = lock.LazyWriteLock(lock_dir, 60.0)
00150         acquired = _lock.acquire(timeout)
00151         if acquired:
00152             self._lock = _lock
00153         else:
00154             self._lock = None
00155             err = "Can't acquire %s lock in %s" % (mode, lock_dir)
00156             logging.error(err)
00157             raise CacheError(err)

Here is the caller graph for this function:

Definition at line 90 of file caching.py.

00090 
00091     def mtime(self):
00092         # DEPRECATED for checking a changed on-disk cache, please use
00093         # self.uid() for this, see below
00094         try:
00095             return os.path.getmtime(self._fname)
00096         except (IOError, OSError):
00097             return 0

Here is the caller graph for this function:

def MoinMoin.caching.CacheEntry.needsUpdate (   self,
  filename,
  attachdir = None 
)

Definition at line 111 of file caching.py.

00111 
00112     def needsUpdate(self, filename, attachdir=None):
00113         # following code is not necessary. will trigger exception and give same result
00114         #if not self.exists():
00115         #    return 1
00116 
00117         try:
00118             ctime = os.path.getmtime(self._fname)
00119             ftime = os.path.getmtime(filename)
00120         except os.error:
00121             return 1
00122 
00123         needsupdate = ftime > ctime
00124 
00125         # if a page depends on the attachment dir, we check this, too:
00126         if not needsupdate and attachdir:
00127             try:
00128                 ftime2 = os.path.getmtime(attachdir)
00129             except os.error:
00130                 ftime2 = 0
00131             needsupdate = ftime2 > ctime
00132 
00133         return needsupdate

def MoinMoin.caching.CacheEntry.open (   self,
  filename = None,
  mode = 'r',
  bufsize = -1 
)
open the cache for reading/writing

Typical usage:
    try:
cache.open('r')  # open file, create locks
data = cache.read()
    finally:
cache.close()  # important to close file and remove locks

@param filename: must be None (default - automatically determine filename)
@param mode: 'r' (read, default), 'w' (write)
     Note: if mode does not include 'b' (binary), it will be
           automatically changed to include 'b'.
@param bufsize: size of read/write buffer (default: -1 meaning automatic)
@return: None (the opened file object is kept in self._fileobj and used
 implicitely by read/write/close functions of CacheEntry object.

Definition at line 168 of file caching.py.

00168 
00169     def open(self, filename=None, mode='r', bufsize=-1):
00170         """ open the cache for reading/writing
00171 
00172         Typical usage:
00173             try:
00174                 cache.open('r')  # open file, create locks
00175                 data = cache.read()
00176             finally:
00177                 cache.close()  # important to close file and remove locks
00178 
00179         @param filename: must be None (default - automatically determine filename)
00180         @param mode: 'r' (read, default), 'w' (write)
00181                      Note: if mode does not include 'b' (binary), it will be
00182                            automatically changed to include 'b'.
00183         @param bufsize: size of read/write buffer (default: -1 meaning automatic)
00184         @return: None (the opened file object is kept in self._fileobj and used
00185                  implicitely by read/write/close functions of CacheEntry object.
00186         """
00187         assert self._fileobj is None, 'caching: trying to open an already opened cache'
00188         assert filename is None, 'caching: giving a filename is not supported (yet?)'
00189         assert 'r' in mode or 'w' in mode, 'caching: mode must contain "r" or "w"'
00190 
00191         if 'b' not in mode:
00192             mode += 'b'  # we want to use binary mode, ever!
00193         self._mode = mode  # for self.close()
00194 
00195         if self.locking:
00196             self.lock(mode)
00197         try:
00198             if 'r' in mode:
00199                 filename = self._fname
00200                 self._fileobj = open(filename, mode, bufsize)
00201             elif 'w' in mode:
00202                 # we do not write content to old inode, but to a new file
00203                 # so we don't need to lock when we just want to read the file
00204                 # (at least on POSIX, this works)
00205                 filename = None
00206                 fd, filename = tempfile.mkstemp('.tmp', self.key, self.arena_dir)
00207                 self._tmp_fname = filename
00208                 self._fileobj = os.fdopen(fd, mode, bufsize)
00209         except IOError, err:
00210             if 'w' in mode:
00211                 # IOerror for 'r' can be just a non-existing file, do not log that,
00212                 # but if open fails for 'w', we likely have some bigger problem:
00213                 logging.error(str(err))
00214             raise CacheError(str(err))

Here is the caller graph for this function:

def MoinMoin.caching.CacheEntry.read (   self,
  size = -1 
)
read data from cache file

@param size: how many bytes to read (default: -1 == everything)
@return: read data (str)

Definition at line 215 of file caching.py.

00215 
00216     def read(self, size=-1):
00217         """ read data from cache file
00218 
00219         @param size: how many bytes to read (default: -1 == everything)
00220         @return: read data (str)
00221         """
00222         return self._fileobj.read(size)

Here is the caller graph for this function:

Definition at line 287 of file caching.py.

00287 
00288     def remove(self):
00289         if self.locking:
00290             self.lock('w')
00291         try:
00292             try:
00293                 os.remove(self._fname)
00294             except OSError:
00295                 pass
00296         finally:
00297             if self.locking:
00298                 self.unlock()
00299 
00300 

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 98 of file caching.py.

00098 
00099     def size(self):
00100         try:
00101             return os.path.getsize(self._fname)
00102         except (IOError, OSError):
00103             return 0

Return a value that likely changes when the on-disk cache was updated.

    See docstring of MoinMoin.util.filesys.fuid for details.

Definition at line 104 of file caching.py.

00104 
00105     def uid(self):
00106         """ Return a value that likely changes when the on-disk cache was updated.
00107 
00108             See docstring of MoinMoin.util.filesys.fuid for details.
00109         """
00110         return filesys.fuid(self._fname)

release the lock.

Definition at line 158 of file caching.py.

00158 
00159     def unlock(self):
00160         """
00161         release the lock.
00162         """
00163         if self._lock:
00164             self._lock.release()
00165             self._lock = None

Here is the caller graph for this function:

def MoinMoin.caching.CacheEntry.update (   self,
  content 
)

Definition at line 246 of file caching.py.

00246 
00247     def update(self, content):
00248         try:
00249             if hasattr(content, 'read'):
00250                 # content is file-like
00251                 assert not (self.use_pickle or self.use_encode), 'caching: use_pickle and use_encode not supported with file-like api'
00252                 try:
00253                     self.open(mode='w')
00254                     shutil.copyfileobj(content, self)
00255                 finally:
00256                     self.close()
00257             else:
00258                 # content is a string
00259                 if self.use_pickle:
00260                     content = pickle.dumps(content, PICKLE_PROTOCOL)
00261                 elif self.use_encode:
00262                     content = content.encode(config.charset)
00263 
00264                 try:
00265                     self.open(mode='w')
00266                     self.write(content)
00267                 finally:
00268                     self.close()
00269         except (pickle.PicklingError, OSError, IOError, ValueError), err:
00270             raise CacheError(str(err))

Here is the call graph for this function:

Here is the caller graph for this function:

def MoinMoin.caching.CacheEntry.write (   self,
  data 
)
write data to cache file

@param data: write data (str)

Definition at line 223 of file caching.py.

00223 
00224     def write(self, data):
00225         """ write data to cache file
00226 
00227         @param data: write data (str)
00228         """
00229         self._fileobj.write(data)

Here is the caller graph for this function:


Member Data Documentation

Definition at line 78 of file caching.py.

Definition at line 74 of file caching.py.

Definition at line 77 of file caching.py.

Definition at line 80 of file caching.py.

Definition at line 79 of file caching.py.

Definition at line 71 of file caching.py.

Definition at line 67 of file caching.py.

Definition at line 68 of file caching.py.

Definition at line 66 of file caching.py.

Definition at line 70 of file caching.py.

Definition at line 69 of file caching.py.


The documentation for this class was generated from the following file: