[ZODB-Dev] Pluggable transactions logic

JohnD.Heintz JohnD.Heintz
Mon, 30 Jul 2001 13:20:40 -0500


I'm responding to a mix of both of Steve's email below.

On Saturday 28 July 2001 04:01, Steve Alexander wrote:
> 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 thin=
k
> 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 object=
s
> 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?

I did have a lower level interface in mind, and this conversation might h=
ave=20
helped me crystalize it more.  Here is what I am now thinking would be=20
required to expose in the Transaction Framework to build these other serv=
ices=20
on top of:

def registerTransactionCreation(callback):
=09"""callback.onTranactionCreated(transaction)
=09These callbacks would never be implicitly removed"""

def unreisterTransactionCreation(callback):
=09"""Removes a callback explicitly"""

def get_transaction(_id=3Dthread.get_ident):
=09"""Global function to lookup transaction objects by some id"""

class Transaction:
=09def registerBeginCallback(callback):
=09=09"""callback.onTransactionBegin(transaction)
=09=09This callback would never be implicitly removed"""

=09def unregisterBeginCallback(callback):
=09=09"""Removes the callback explicitly"""

=09def registerCommitCallback(callback):
=09=09"""callback.onTransactionCommit(transaction)
=09=09These callbacks would be called after successful commit.
=09=09After either commit() or abort() they would be cleared"""

=09def registerAbortCallback(callback):
=09=09"""callback.onTransactionAbort(transaction)
=09=09These callbacks would be called after abort.
=09=09After either commit() or abort() they would be cleared"""

=09def attach(_id=3Dthread.get_ident):
=09=09"""Create a mapping from _id() to this Transaction"""

=09def remove(_id=3Dthread.get_ident):
=09=09"""Remove any mapping from _id() to this Transaction"""

class CommitActivity:
=09def _begin(subtransaction=3D0):
=09=09"""Called during tpc_begin processing.
=09=09Includes flag to signal whether subtransaction or not."""

=09def _vote(subtransaction=3D0):
=09=09"""Called during tpc_vote processing.
=09=09Includes flag to signal whether subtransaction or not."""

=09def _finish(subtransaction=3D0):
=09=09"""Called during tpc_finish processing.
=09=09Includes flag to signal whether subtransaction or not."""

=09def _abort(subtransaction=3D0):
=09=09"""Called during tpc_abort processing.
=09=09Includes flag to signal whether subtransaction or not."""

=09def _postCommit(subtransaction=3D0):
=09=09"""Called from Transaction.registerCommitCallback().
=09=09Includes flag to signal whether subtransaction or not."""

I think that given registerTransactionCreation() and=20
Transaction.registerBeginCallback() storing their callback arguments is=20
should be possible to re-register appropriate Commit and Abort callbacks =
as=20
necessary to support either long lived or per-transaction Plugin=20
functionality.

>
> ---
>
> 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.

I'm hoping that some API like the above will contain enough functionality=
 to=20
be able to support both of these.

To pick an example core ZODB Transaction behavior right now: the=20
get_transaction() function has a hidden counterpart: free_transaction(). =
=20
This function is used to clean up the internal dictionary that maps threa=
d id=20
to Transaction object.  Because it is hidden and hard-coded to be called=20
based on commit() logic and Transaction.id value it isn't extensible.

I would imagine Zope could use the above API plus a callback=20
onTransactionBegin(t) to register an onTransactionCommit(t) callback that=
=20
would call t.detach() and replicate the use of free_transaction().

>
> 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(....)

I'm not a fan of these kinds of approaches.  I'm not very good at predict=
ing=20
the future and exposing these purpose build interfaces from the core outw=
ard=20
gives me an uneasy feeling.

>
> --
> Steve Alexander
> Software Engineer
> Cat-Box limited

On Saturday 28 July 2001 05:00, Steve Alexander wrote:
> Another difference between what you want here, and what I implemented i=
n
> TransactionAgents, is that when you register a Transaction Agent, the
> registration lasts only for that one transaction.
>

It's still a little klunky in my interfaces above, but=20
onTransactionCreated(t) and onTransactionBegin(t) would both be long live=
d=20
registrations.  If I wanted a service to handle onTransactionCommit(t) fo=
r=20
every Transaction to account for two queues or various agents I could:
- Define my module to register for onTransactionCreated(t) events to get=20
access to all the Transactions in the system.

- Have the onTransactionCreated(t) code register a onTransactionBegin(t)=20
handler that creates CommitActivity objects or registers=20
onTransactionAbort(t) and onTransactionCommit(t) handlers.

Does this look like a starting point?

John


--=20
=2E . . . . . . . . . . . . . . . . . . . . . . .

John D. Heintz | Senior Engineer

1016 La Posada Dr. | Suite 240 | Austin TX 78752
T 512.633.1198 | jheintz@isogen.com

w w w . d a t a c h a n n e l . c o m