In a couple weeks I'll be doing some work on Firefox-as-a-platform-SDK 
(replacement for XULRunner) and addon infrastructure work.  Part of that latter 
bit would be support for asynchronous file operations in the AddonManager.

The file operations, however, have to be revertable in the face of an error.

To support that (and for other needs), I've written an asynchronous transaction 
manager (ATM) module, modeled after Mozilla's own transaction manager code.  It 
should be more than adequate for AddonManager:  one transaction comprises 
multiple asynchronous actions in a microtask.

I am looking for someone who's willing to review this code and to help me 
refine it for mozilla-central.  The reviewer should understand asynchronous 
Promise operations, preferably the OS.File promises, and should be willing to 
learn about the existing editor/txmgr code we currently have.  (Like the rest 
of the editor code, I believe txmgr is basically unowned right now.  But it is 
actually a pretty good component!)

I'm also looking for a place to put an AsyncTransactionManager in the source 
code, probably in toolkit/modules, I'm thinking.

Here's how it currently works:

* The module exports a PromiseAction constructor with do, undo, redo methods.  
Each method should be replaced by the caller with a method that returns a 
Promise object.  A do() method represents executing the action for the first 
time.  The undo() and redo() methods represent reversing and restoring the 
single asynchronous operation of do(), respectively.

* A transaction is basically a sequence of PromiseAction objects.

* The ATM provides a doTransaction() method.  The arguments currently are:
*# intent:  A string describing the transaction as a whole.
*# code:  An arbitrary value, recommended as a flag for merging the transaction 
into the previous transaction.
*# merge: A method of the new transaction object: to determine if a following 
transaction should be merged into the transaction.
*# task: A generator function yielding several PromiseAction objects in 
sequence.

The transaction object is built from these.  Thus, the user doesn't need to 
pass in Transaction objects.

* If a PromiseAction's do() method yields a Promise which is eventually 
rejected, this is treated as an abort, and the ATM attempts to roll back the 
transaction by calling each successful PromiseAction's undo() method, in 
reverse order.

* Likewise, an aborted ATM.undoTransaction() call results in successfully 
undone PromiseAction instances having their redo() methods called in forward 
order.  Similarly, an aborted redo() call results in undo() calls on 
PromiseAction objects, in reverse order.

* The ATM provides undoTransaction() and redoTransaction() methods, that take 
no arguments.  These undo and redo individual transactions.

* While asynchronous operations on a transaction are underway, calls to the 
ATM's doTransaction(), undoTransaction() or redoTransaction() methods 
automatically throw an exception.

* There is also support for listening to transaction manager events 
(["willExecute", "didExecute", "willAttemptMerge", "didAttemptMerge"], ["do", 
"undo", "redo"]).

I have a test suite already written and passing in Jasmine code; I'm perfectly 
willing and capable to port the tests to xpcshell-tests.

Alex Vincent
_______________________________________________
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform

Reply via email to