[Persistence-sig] A simple Observation API

Guido van Rossum guido@python.org
Mon, 29 Jul 2002 17:56:53 -0400


> At 05:18 PM 7/29/02 -0400, Guido van Rossum wrote:
> >Some questions about Phillip's Observable protocol.  Wby does it
> >have to be so complicated?  E.g. if you have to do something
> >special for method that touches an attribute without doing a
> >setattr operation on it, why not have the magic be inside that
> >method rather than declare a wrapper?  (The wrapper looks like it
> >is much more expensive than another way of flagging a change would
> >be.)
> 
> It's only for event compression, otherwise putting a simple flag
> operation in the method would indeed be more lightweight.  Of
> course, I'm pretty sure I could write a bytecode-hacking version
> that would recode the underlying method to include the necessary
> wrapping code around its body, making it just as fast as putting the
> code inline.  But I didn't want to put that much effort into an
> example.  :)

I hope you were really only joking.  Hacking bytecode is inexcusable
mixing of abstraction levels.

> >What exactly is the point of collapsing multiple setattr() ops
> >together?  Just performance?  Or is there a semantic reason?  If
> >just performance, where is the time going that you're trying to
> >save?
> 
> Semantics plus performance.  The semantic part is that some
> "database" systems (e.g. LDAP) inherently don't support
> transactions, AND must receive a semantically valid set of
> attributes in a single update operation.  I may be overgeneralizing
> this aspect, however.

I'm guessing that you'll have to do this differently anyway,
e.g. cache all changes and them force them out all at one with a
commit() operation.

> The performance save is for situations like Tim Peters' distributed
> cache example.  If a change notification is going to cause network
> traffic, it would be a good idea to minimize the number of such
> notifications.  It's a common situation (IMHO) to change multiple
> attributes in a set of related methods, so this supports that
> scenario while ensuring a minimal set of update events are issued.

Isn't there a way to do this in a less obtrusive way, e.g. by
buffering?  I don't know much of this application area, but the
mechanism you are proposing looks very heavy-handed.  I would expect
that in a realistic system, most methods would grow wrappers.  And
this *still* doesn't prevent bugs like updating a list attribute by
calling its append() method without somehow flagging this operation.

(Flagging changes at the method call level seems too course-grained.
What about a method that only occasionally makes a change to a given
attribute?)

> >What's the use case for declaring a method as "touches an attribute
> >but that change should be ignored"?  (If it's only __init__, a
> >lighter-weight mechanism might be sufficient.)
> 
> I discovered the __init__ issue when I went to write the example
> code, and adding an ignore list seemed like the simplest way to
> solve it quickly without adding a metaclass or something else
> special to handle __init__.  Also, I know I've frequently written
> classes which do the bulk of their attribute setup in methods other
> than __init__, and imagine others do as well.  These days I use PEAK
> attribute binding descriptors that automatically initialize
> attributes on first-use, instead, but I wrote the Observable example
> assuming "plain-jane", "mainstream" Python with no special
> metaclasses or the like.

That's good, because I have no idea what PEAK is. :-)

Anyway, if the special handling is mostly for __init__ (or things it
calls), then a metaclass could make the notation a bit prettier.

> In general, as to the features of the API, I wrote this mostly based
> on the use cases that other folks had, although I'm certainly not
> against having event compression.  :) My own requirements in the API
> are only the changeable "get" hook, and that notification of writes
> takes place after the modifications.
> 
> The idea of using method wrappers to incorporate the metadata about
> what attributes are modified, was an attempt to help mask
> implementation details from the "naive" user.  It seemed to me a
> less invasive form of "dead chicken waving", and also allowed for
> alternative implementation strategies for the observable's internal
> mechanism.

Maybe it's just too early to start proposing code?  Or has the
discussion already moved to IRC?  I'm curious about why the message
flow just stopped.

--Guido van Rossum (home page: http://www.python.org/~guido/)