Notes on persistent code/classes
Z2 ZClasses
Note that I'm not certain that ZClasses work in Zope 2.8.
- For ZClasses
- All data in __getinitargs__
- Invalidation calls a special method on the jar to set the
klass data:
- Load a copy of the class
- Copy the old dict contents
XXX This doesn't support changing the bases or the name :(
- ZClasses are never ghosts. We use a bunch of special casing to arrange this, I believe.
- For non-persistent instances of persistent classes
Probably doesn't work
- For persistent instances of persistent classes
- We use the __module__ and __name__ of the persistent class,
just like we would for a regular class.
For ZClasses, the __module__ is a guid.
- When we load an instance, we use a special class factory that
takes a module name and class name.
For ZClasses, we ignore the class name and use the module name to look up the class in a mapping from classid->class, where the __module__ is the class id.
- We use the __module__ and __name__ of the persistent class,
just like we would for a regular class.
Z3 persistent code classes
- I don't think classes require any special cases.
- Use new __getnewargs__ protocol to get initial arguments, which, I think include just the name and bases.
- Persistent references include the newargs. If this is true, then we also can't change the bases.
Decisions
- Storage of instances of persistent classes
Options:
A. Use direct reference to class (as in current ZODB 4)
Pros:
- Consistent treatment of persistent and non-persistent instances. Most like standard pickle protocol (ignoring protocol 0).
- Don't require the database code to have a table mapping class names to classes.
Cons:
- Need to reimplement broken-object support.
The current broken-object facility relies on name-based class lookup.
- Need to reimplement database export/import to make sure
that classes are not exported by virtue of exporting
instances. This could be quite difficult. In fact, we
probably need to prototype this prior to any final
decision to adopt option A.
The difficulty arises from the same problem that complicates option B. The standard pickle protocol (ignoring protocol 0) doesn't allow us to detect whether a class is being pickled as part of an instance serialization, or by virtue of pickling the container of a class.
- Detection of certain errors is hidden. Consider deletion of a class. If direct references are used, then instances are initially unaffected by the class deletion, since they still have references. On the other hand, if name-based references are used, then instances will be broken much sooner, which is probably preferable. Similarly, if a class is added back, the broken instances will be reattached to the new class. If direct references are used, it could be very difficult to connect the instances of a deleted class with a replacement.
B. Use named reference to class (as in current ZODB 3)
Cons:
- Can't do for non-persistent instances without using a custom pickle protocol
C. Hybrid (possibly interim) approach
Use named references for persistent instances and direct references for non-persistent instances
Note that this is really the approach used by ZODB.