[TransWarp] PEAK persistence requirements and implementation thoughts

Phillip J. Eby pje at telecommunity.com
Fri Jun 28 14:54:53 EDT 2002

At 08:05 PM 6/28/02 +0200, Roché Compaan wrote:
>Hi Philip
>> CRITICAL: Clients of an Element should not be required to participate in 
>> persisting it.
>This sounds great!  From my understanding from the rest of your email
>elements are persisted per attribute change if attribute changes are not
>nested in operations.

That was the idea, yes.  However, my later posts outline a very different
mechanism, based on ZODB4 (the Persistence system of Zope 3).

>> CRITICAL: "Intensional state".  An Element should be able to refer to its 
>> state in terms of a key.  If a cached Element refers to a state 
>> object that 
>> was cached across transactions, and the cached state has changed 
>> keys, the 
>> cached Element should not re-use the cached state.
>I don't quite understand "and the cached state has changed keys".  If an
>element is cached by key how can this key ever change?  

Because not all unique keys are immutable.  For example, in the company I
work for, a person's login name can change when they get married (due to
last name change), but the login name is still a unique key.  A transaction
in which we are changing their login ID, would have a change of a key that
the object is cached by.

TW.Database.DataModel actually implements this, though with a few ugly holes.

>this also seems fundamental in understanding the last couple of paragraphs
>in you proposal where you talk a lot about key changes.

Yes.  It's also what makes the concept so damn complicated!  I think the
ZODB4-based approach I came up with this morning will work better, by
giving up on caching by mutable keys and demanding that objects have at
least one immutable primary key which can be used as an oid.

>> "State" objects, similar to TW's old Record objects, maintain a pair of 
>> mappings of field names to immutable atomic values (or tuples 
>> thereof).  One mapping represents "persistent" state, i.e., what is 
>> currently in the underlying DB.  The other represents "dirty" state, i.e. 
>> what has been written but not yet sent to the DB.
>I find the name "State" very ambiguous, especially in a database context
>anything from transactions, records and the database itself are statefull.  
>It sounds like the mappings you mention above are really "Records" or maybe
>"RecordSate" and that "State" is characteristic of a particular mapping. 
>When I re-read your mail with that in mind I understood a lot more.

I was using "state" instead of "record" to avoid premature association
between the idea I was exploring, and the already existing Record object of
TW.Database.DataModel, whose conceptual basis is not quite the same.  Also,
a "state" might be based on another "state", or on something stored in a
file, or even some kind of system process state or memory structure.  So
"state" was actually appropriately generic for what I had in mind.

>> When a state object is looked up, the Element must check 
>> its own nesting count, and if positive, it should pass a "begin" 
>> message to 
>> the newly-retrieved state.
>I don't understand this.  I thought that calls to beginOp are explicitly
>and optionally made by the Element - it sounds like something automatic is 
>happening here.

What that section meant is, if an Element loads a state object (e.g. its
LDAP state is loaded but not its RDBMS state, and you try to access an
RDBMS-backed attribute), and the Element is already in a beginOp() state,
it should send a beginOp() to the freshly-loaded state object.  This is
because when the Element endOp()'s sufficiently, it will send an endOp() to
all its loaded state objects, which would be a mismatched begin/end count
if it didn't do this.

In any case, I think this is all going to be moot with the ZODB4-based

More information about the PEAK mailing list