[Zope-ZEO] Cascading storages

Eric Jacobs eaj@ricochet.net
Wed, 13 Dec 2000 22:39:59 EDT


I wanted to make a ZODB that is backed by a list of storages,
with one read-write and the rest read-only. This is kind of
the generalization of idea behind DemoStorage. I needed to
be able to save the changes, so DemoStorage wouldn't work.

Not knowing much about the system, my naive attempt was:

class StorageMixer:

    	def __init__(s, l):
        		s.List = l
        		s.Top = l[0]
        		for n in s.Top.__dict__.keys():
            			if not hasattr(s, n):
                				setattr(s, n, getattr(s.Top, n))
        		cl = [s.Top.__class__]
        		for c in cl:
            			for n in c.__dict__.keys():
                				if not hasattr(s, n):
                    					setattr(s, n, getattr(s.Top, n))
            			cl.extend(list(c.__bases__))
		
    	def __len__(s):
        		r = 0
        		for z in s.List:
            			r = r + len(z)
        		return r
	
    	def load(s, oid, version):
        		for z in s.List:
            			try:
                				return z.load(oid, version)
            			except KeyError:
                				pass
        		raise KeyError, oid


To my surprise, this almost worked. If I had a database db1,
I could create a new database db2

db = ZODB.DB(StorageMixer([FileStorage("db2"), FileStorage("db1")]))

that would collect only the changes, leaving db1 unchanged.

Unfortunately, after adding a new storage to the "stack" and
making minor changes in a couple of sessions, something goes
wrong. An object might disappear, or turn into another object.
My instinct is that something is going wrong in the garbage
collection and something is being deallocated too soon, but
I'm not sure how to proceed. Can this even be done?
--