On Tue, 2002-11-26 at 11:52, Wayne Larsen wrote: > As a related question, do you > know how MiddleKit manages caching?
MiddleKit keeps a cache (essentially a dictionary) of references to each objects which it has loaded. Also, any object which has a "List of" attribute will cache the list of objects, so it doesn't have to query the database each time. > I wonder if MiddleKit has a mechanism to discard objects in memory? ObjectStore has a clear() method which can be called if there are no outstanding changes; it causes the store to clear its cache. All subsequent fetch*() calls will instantiate fresh objects. Be careful not to shoot yourself in the foot, though: if you have a reference to a middle object, then call store.clear(), and change the objects's attributes without re-fetching it from the store, you will probably end up with undefined results. :) > I would be interested in seeing your solution. It > seems like a good compromise, since it would apply to > all MiddleKit objects. Ok, here goes: 1. If you're not using Webware from CVS, you need to apply the attach patch to your Webware/WebKit directory, which fixes a couple of oversights in the SessionStore.py and SessionDynamicStore.py files. These fixes make it possible to set our own encoder/decoder for sessions. If you're using CVS, just do an update, since I checked in these fixes this afternoon. 2. Stick the attached MiddlePickle.py file somewhere in your PYTHONPATH. 3. Now you just need to arrange for this custom encoder/decoder to be used. I override Application and do it there, but you'll probably want to do it in your contextInitialize() method, or whereever you instantiate your global store. Assuming that 'store' is your global store instance, and 'app' is the application instance, the code looks something like this: import MiddlePickle MiddlePickle.setStore(store) app.sessions().setEncoderDecoder(MiddlePickle.dump,MiddlePickle.load) cheers, Jason
Index: SessionStore.py =================================================================== RCS file: /home/jdhildeb/projects/mobile/cvs/Webware/WebKit/SessionStore.py,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- SessionStore.py 2002/08/17 20:30:44 1.1.1.1 +++ SessionStore.py 2002/08/17 21:29:27 1.2 @@ -47,7 +47,8 @@ from cPickle import load, dump except ImportError: from pickle import load, dump - self.setEncoderDecoder(dump, load) + self._encoder = dump + self._decoder = load ## Access ## Index: SessionDynamicStore.py =================================================================== RCS file: /home/jdhildeb/projects/mobile/cvs/Webware/WebKit/SessionDynamicStore.py,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -r1.1.1.1 -r1.2 --- SessionDynamicStore.py 2002/08/17 20:30:44 1.1.1.1 +++ SessionDynamicStore.py 2002/08/17 21:23:24 1.2 @@ -2,7 +2,7 @@ import SessionMemoryStore, SessionFileStore import os, time, threading -debug = 0 +debug = 1 class SessionDynamicStore(SessionStore): """ @@ -147,7 +147,9 @@ finally: self._lock.release() - + def setEncoderDecoder(self, encoder, decoder): + self._fileStore.setEncoderDecoder(encoder, decoder) + SessionStore.setEncoderDecoder(self,encoder,decoder) ## Application support ##
from pickle import Pickler as _Pickler from pickle import Unpickler as _Unpickler from MiddleKit.Run.MiddleObject import MiddleObject _store = None class Pickler(_Pickler): def persistent_id( self, object ): if isinstance( object, MiddleObject ) and object.isInStore(): return object.sqlObjRef() else: return None class Unpickler( _Unpickler ): def __init__(self,file,store=None): _Unpickler.__init__(self,file) if not store: store = _store assert store self._store = store def persistent_load( self, pid ): return self._store.fetchObjRef(long(pid)) def setStore(store): global _store _store = store def dump(object, file, bin = 0): Pickler(file, bin).dump(object) def load(file,store=None): return Unpickler(file,store).load()