[elephant-devel] recreate-instance-using-class

Ian Eslick eslick at csail.mit.edu
Tue Jan 8 15:31:13 UTC 2008


Actually I think we definitely need to fix this.  Quite a few people  
have run into the problem that we're violating the CLOS contract on  
make-instance and that we should not use the same CLOS calling path  
for re-initialization that we use for initial creation.  I think we  
should require new contracts rather than messing with familiar ones.

One proposal was to create a placeholder class and then call change- 
class on it, but that still evokes the initargs for new slots and  
creates problems of its own.  Another one is to make a cheap  
placeholder that is only initialized when touched, which I like but  
can't think of how to implement.

As the next step, I think we probably want to figure out, for  
deserialized instances, how to create a minimal instance, initializing  
transient slots only, handle any schema evolution we choose to  
implement and then call a generic function (reconstitute-instance)  
that users can define methods on to do any deserialization time  
specialization.  This way the users can do the usual 'on creation'  
specialization on initialize-instance without having it called  
multiple times in unexpected ways.

The other benefit is that we do less total computation when we load  
instances into memory, especially when we are unlikely to access them.

The trick is to initialize the instance and transient slots without  
calling all the make-instance, initialize-instance machinery.  I'd  
have to go back and get my head around the MOP details again to  
suggest the best way to do this (parallel code, checks in initialize- 
instance, etc).  The current initialization code is actually pretty  
ugly which is undoubtably why there are so many problems trying to  
patch it, so it could really do with a clean rewrite.

Ian

On Jan 8, 2008, at 9:41 AM, Robert L. Read wrote:

> I agree completely with Ian.
>
> In fact I have now spent a very embarrassing 5 days trying to modify  
> the
> ele-postmodern interface to use "recreate-instance" based on Sean's
> patches, and have failed miserably.  This is the first time in my  
> career
> this has ever happened to me.
>
> I wasted this time in part to learn about postmodern, and in part
> because I didn't want to reject Sean's patch, which apparently he and
> one other person need.  However, it seems clear now that we need to  
> back
> Sean's patch out of the repository and answer more of the questions  
> that
> Ian raises.  In particular, it was never perfectly clear to me why  
> Sean
> thought avoiding the call to "make-instance" was so important.  I
> understand of course that if one has overloaded make-instance with  
> some
> functionality that has nothing to do with reconstituting the object,  
> the
> current implementation of Elephant will erroneously invoke that; but  
> it
> is not clear if Elephant should change to suit that, or if the user
> should simply move that functionality out of make-instance.  That is
> part of the policy question we will have to answer.
>
> On Tue, 2008-01-08 at 08:50 -0500, Ian Eslick wrote:
>> Hi Alex,
>>
>> I don't think any of the current developers have sat down and really
>> thought through how the entire MOP interface _should_ work in light  
>> of
>> our learning.  My guess is that getting all this right can best be
>> accomplished by rationally designing all the functionality from
>> scratch, and rewrite the persistence protocol as necessary to
>> accommodate the new design.  I learned the MOP during my rewrite a
>> year or two ago, so I'm sure there is some evidence of this in the
>> current implementation.  With the expanded test suite, debugging the
>> new MOP implementation shouldn't be overwhelmingly problematic.
>>
>> There are several orthogonal requirements being satisfied during
>> initialization that should be separated clearly in the design:
>>
>> 1) CLOS instance mgmt (such as allocate-instance)
>> 2) Elephant instance mgmt (all elephant instances need an OID, a home
>> store, etc)
>> 3) CLOS/Elephant slot value initialization
>>    a) During creation (all arguments, initforms; write db)
>>    b) During deserialization (initforms for transient slots only)
>> 4) Slot value access
>>    i) For now, always directly to DB
>>    ii) maintain indexes
>>
>> Every time a persistent object is created or recreated, steps #1 and
>> #2 are required.  #1 and #2 are all tied up in shared-initialize and
>> initialize-instance, and I don't think there is a clean separation
>> between those steps and the steps in #3 that handle the  
>> initialization
>> vs. re-initialization problems.
>>
>> Additional complications:
>> - Schema evolution makes this even more exciting and requires
>> intervention in elephant instance management, slot value
>> initialization and perhaps even slot value access.
>> - An additional complication has been dealing with variations among
>> different MOP implementations.
>> - We've talked about having a clean way to allow slots to be cached,
>> i.e. to be declared unshared so they only access the DB on writes, or
>> managed which means only written when 'saved'
>>
>> Ian
>>
>>
>> On Jan 8, 2008, at 7:10 AM, Alex Mizrahi wrote:
>>
>>> helo
>>>
>>> there was a patch that alters the way how objects that are
>>> deserialized are
>>> created: it uses allocate-instance and bypasses normal  
>>> initialization
>>> sequence of make-instance.
>>>
>>> however, there was no documentation given how this is supposed to
>>> work, so i
>>> thought this shouldn't affect applications.
>>>
>>> but we've found that sometimes it has disastrous effects in some
>>> cases.
>>>
>>> for example, we've found that "strange bug" Robert saw in postmodern
>>> backend
>>> happens because initialize-instance of pm-btree is not called.
>>>
>>> it seems now we should use recreate-instance instead of initialize-
>>> instance,
>>> because descendants of "persistent", like btrees and other internal
>>> classes,
>>> are completely deprived from normal Common Lisp initialization
>>> functions. if
>>> this is intentional, probably it's worth documenting this, because
>>> finding
>>> such stuff from weird bugs isn't very pleasant.
>>>
>>> also, it seems initargs/initforms won't be initialized on recreated
>>> instances of persistent, at least i don't see any way how they could
>>> be
>>> initialized. we should forget about this functionality for internal
>>> elephant's persistent classes?
>>>
>>> or this damage was not intentional? as i understand, elephant users
>>> are
>>> supposed to work with persistent-object, but not persistent class,
>>> so maybe
>>> this patch should only affect persistent-object?
>>>
>>> it's also quite strange that recreate-instance for persistent-object
>>> calls
>>> shared-initialize, but for persistent it doesn't. looks like
>>> intentional
>>> sabotage! :)
>>>
>>> but it's not clear how this stuff should affect descendants of
>>> persistent-object. if people used initialize-instance :after to
>>> intialize
>>> transient slots, how are they supposed to intialize them now?
>>> shared-initialize :after? or they should use ele::recreate-instance?
>>>
>>> with best regards, Alex 'killer_storm' Mizrahi.
>>>
>>>
>>>
>>> _______________________________________________
>>> elephant-devel site list
>>> elephant-devel at common-lisp.net
>>> http://common-lisp.net/mailman/listinfo/elephant-devel
>>
>> _______________________________________________
>> elephant-devel site list
>> elephant-devel at common-lisp.net
>> http://common-lisp.net/mailman/listinfo/elephant-devel
>
> _______________________________________________
> elephant-devel site list
> elephant-devel at common-lisp.net
> http://common-lisp.net/mailman/listinfo/elephant-devel




More information about the elephant-devel mailing list