##################################################
# 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()
|