[ZODB-Dev] Pluggable transactions logic

Steve Alexander steve@cat-box.net
Sat, 28 Jul 2001 10:01:58 +0100


Chris Withers wrote:
 >> * The ZODB gets an API to support plugging in arbitrary processing
 >>  at various points in transaction processing.
 >>
 >> The latter approach is best if you want to keep ZODB simple, but
 >> allow arbitrary other more complex transaction processing to
 >> happen, in arbitrary combinations.
 >>
 >
 > This sounds like the way forward to me...
 >
 > Just so it's recorded somewhere, my API use case would be something
 > like:
 >
 > from ZODB import registerAgent, COMMIT
 >
 > class MyObj(PortalContent): # My content storage class pass
 >
 > def myMethod(obj) obj.portal_catalog.catalog_object(obj)
 >
 > registerAgent(myMethod,[MyObj],COMMIT,100)
 >
 > The first argument is the method to be called.
 >
 > The second argument is a list of classes. This indicates that this
 > method should be called when objects of that class are committed.
 > Maybe that could be interfaces as well/instead? If this list is
 > empty, the method gets called for all types of object.
 >
 > COMMIT is an integer constant indicating at what point in the
 > transaction myMethod gets called.
 >
 > 100 is the priority. Methods are called in order of their priority.

Do you really need a number to represent the priority? I thought about 
that, but I can't think of a case that's not handled by having just two 
queues: Rule Agents and Indexing Agents.

Also, have you considered what should happen with the priorities on a 
subtransaction commit?


Take a look in the tests that are with TransactionAgents, and what 
happens when, while an agent is running, it adds another agent, and 
commits a subtransaction.

It could be that you only want your agents to run on a complete outer 
transaction (that is, not a subtransaction). However, I need to be able 
to commit subtransactions from my agents.


And are you sure you mean what you say with those classes... how will 
the method know what has happened to instances of the classes in 
question? That is, I think you'll only have access to the new state of 
the instances, so you won't have a baseline against which to tell how 
they've changed. This is what the DataSkin class does in ZPatterns. It 
keeps tracks of how things have changed during a transaction.

I think you're thinking of a much higher-level interface than John or I 
are working with. That's not a bad thing... but I think we need to think 
about the API you'd need to support the interface that your users would 
use to register classes for processing. If I understand correctly what 
you have in mind, you'd need a low-level API to inspect what the objects 
that are being committed during a transaction, and make decisions based 
on that. You'd probably also want to do certain things depending on an 
object's physical path... but that's a Zope thing, not a ZODB thing.
Hmm... perhaps you can throw together a prototype for what you want?

---

Then again, if we're working on a pluggable API for this, I can stick 
with my two queues + subtransaction support, and plug that in. You can 
also plug in your register agents to happen at various points for 
various classes with various priorities stuff.

We probably need to consider what happens when there is a name 
collision. Should the names all be added to the Transaction class, so 
you'd do get_transaction().your_method_here().

Perhaps it would be better to have something like:

get_transaction().agents.register(...)

Then, different plug-ins just need to agree on dividing up the agents 
namespace :-)

Of course, there's also something like:

get_transaction().agents.chrisw.register(...)
get_transaction().agents.TransactionAgents.register(....)

--
Steve Alexander
Software Engineer
Cat-Box limited