################################################## # SPYCE - Python-based HTML Scripting # Copyright (c) 2002 Rimon Barr. # # Refer to spyce.py # CVS: $Id: pool.py 799 2005-07-22 02:19:19Z jbe $ ################################################## import sys, time, os.path import cPickle as pickle import spyce, spyceLock, spyceUtil from spyceModule import spyceModule __doc__ = """Pool module supports the creation of server-pooled objects. The single pool is shared among all Spyce execution context residing on a given server, and remains until the server dies. It is often useful to store database connections, and other variables that are expensive to compute on a per-request basis. """ # todo: should pickle/unpickle go somewhere else, such as request? # this would make it more intuitive for people using SPYCE_GLOBALS # but not pool module def picklefile(): return os.path.join(spyce.getServer().config.tmp, 'spypool.pickle') class pool(spyceModule): def start(self): "Define or retrieve the pool." if spyce.getServer().threaded(): self._pool = self._api.getServerGlobals() return try: f = open(picklefile(), 'rb') except IOError: self._pool = {} return def foo(): spyceLock.file_lock(f, spyceLock.LOCK_SH | spyceLock.LOCK_NB) return True if not spyceUtil.tryForAwhile(foo): raise "timeout opening pool pickle file for read" try: try: self._pool = pickle.load(f) except EOFError, pickle.UnpicklingError: spyce.DEBUG("Warning: unable to complete loading pool from pickle file. A common cause is adding instances of custom classes to the pool. Consider using Spyce in standalone mode to avoid pickle-related limitations.") self._pool = {} finally: spyceLock.file_unlock(f) f.close() def finish(self, err): if spyce.getServer().threaded(): return f = open(picklefile(), 'wb') def foo(): spyceLock.file_lock(f, spyceLock.LOCK_EX | spyceLock.LOCK_NB) return True if not spyceUtil.tryForAwhile(foo): raise "timeout opening pool pickle file for write" try: pickle.dump(self._pool, f, -1) finally: spyceLock.file_unlock(f) f.close() def __getitem__(self, key): "Get an item from the pool." return self._pool[key] def __setitem__(self, key, value): "Set an item in the pool." self._pool[key] = value def __delitem__(self, key): "Delete an item in the pool." del self._pool[key] def keys(self): "Return the pool hash keys." return self._pool.keys() def values(self): "Return the pool hash values." return self._pool.values() def has_key(self, key): "Test of existence of key in pool." return self._pool.has_key(key) def __contains__(self, key): return key in self._pool def setdefault(self, *args, **kwargs): return self._pool.setdefault(*args, **kwargs) def items(self): return self._pool.items() def clear(self): "Purge the pool of all items." return self._pool.clear()