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

Reply via email to