The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Env::Transaction - Perl extension for running a set of operations within a safe, transactional execution model with either ONE- or TWO- phase protocols.

DON'T FORGET! checkout Env-Transaction/t/*.t files from distro dir

SYNOPSIS

  use Env::Transaction;
        sub Env::Transaction::DEBUG { 1; } #that if you want debug infos
        sub task_func { print "brain degeneration stage $_[0]\n"; return 1; }

        my $tx = new Env::Transaction(protocol=>TX_TWO_PHASE_COMMIT,autorollback=>1);
        my $task1 = new Env::Transaction::Task(
                name=>'task_ONE',
                run=>[\&task_func,'run',1],
                undo=>[\&task_func,'undo',1],
                callback=>[\&task_func,'callback',1],
                rc=>[\&task_func,'rc'],
        );
        #...
        #...
        $tx->prepare(
                $task1,
                new Env::Transaction::Task(
                        name=>'task_TWO',
                        #...
                )
        );
        $tx->commit();
        $tx->cleanup();

DESCRIPTION

Hint: I use this module for committing sets of system configurations to one or more servers. This is not an ACID XA compatible transaction module but rather a quick and !dirty way of saving yourself from cleaning up the mess left during a sysadmin fingerpanzer division assault.

METHODS

Env::Transaction::Task::new()

Env::Transaction::AtomicTask::new()

Env::Transaction::CheckpointTask::new()

creates a new task to be registered within a transaction accepting the following parameters:

(

        name=>'taskname',
        run=>[\&coderef,@args],
        rc=>[\&coderef,@args],
        undo=>[\&coderef,@args],
        callback=>[\&coderef,@args],

)

an ::AtomicTask will have its undo method ignored if the task's run method fails. That is, an ::AtomicTask can't modify anything outside unless it succeeds. However, if an ::AtomicTask 'A' succeeds but a later task 'T' fails then 'A''s undo method will get to be executed in the stack rundown process, ofcourse. Ideally there will be only ::AtomicTasks inside a transaction but unfortunately (or fortunately) a normal ::Task can use its undo method to clean its mess on personal failure.

a ::CheckpointTask is just a ::Task that will only run in the callback stage

On 'new' arguments

the 'name' is mandatory. you can later lookup return values of 'TASK_3::run' method from within 'TASK22::callback' method with $tx->results('TASK_3','run')

'run' contains whatever operation you want to execute.

'rc': you can specify a subroutine to check return codes of 'run'. it should return DEFINED if 'run' returned what you expected

'undo': this is a subroutine that should undo whatever 'run' accomplished if a later task fails. it is also used to clean its own mess if the task it is bound to isn't an ::AtomicTask. undo is supposed to always SUCCEED (no failure expected)

'callback': this is a method that will be executed in a row (same order as the tasks were registered with) after the entire transaction was committed successfully. this will allow you to peek into tx stacks, clean tasks mess, etc.

'name', 'run' and 'undo' are mandatory. If no 'rc' is specified then a default one will be used that will check for DEFINED return codes. I advise to use your own 'rc' checkers. 'callback's are optional.

'rc' will get the return values from 'run' appended to the parameters list.

'name', 'run', 'undo', 'rc' and 'callback' arguments are array references. the first element must always be a coderef, the rest are (optional) parameters to be passed to the coderef on its execution.

new methods will return undef on bad parameters.

Env::Transaction::new()

creates a new transaction. accepts the following key=>value parameters:

(

        protocol=>TX_TWO_PHASE_COMMIT | TX_ONE_PHASE_COMMIT
        autorollback=> BOOL_TRUE | BOOL_FALSE

)

transaction protocol

if TX_TWO_PHASE_COMMIT is specified then a task will be transparently committed when $tx->prepare($task) is called. A call of $tx->commit() will never fail. Useful when you have a local master transaction and remote slave transactions and preparing tasks locally means committing tasks remotely. Or just when you dont want your $tx->commit() to fail but rather process the rollbacks at prepare() time.

TX_ONE_PHASE_COMMIT will act normally, $tx->commit()-ing the tasks on explicit request.

autorollback is self-explanatory

Env::Transaction::prepare()

called as $tx->prepare($task1, ......, $taskN);

will register the task(s) within transaction $tx. if TWO-phase protocol was specified at $tx construction then the tasks will also be committed

Env::Transaction::commit()

called as $tx->commit() with no args

will commit the registered tasks and will run the callbacks if any registered (in TWO-phase protocol mode the callbacks will get to run when there is no pending transaction in the queue at the momment the commit() was called).

Env::Transaction::cleanup()

$tx->cleanup()

gives you a chance to clean the task queue and the runstack after a commit()

Env::Transaction::id()

$tx->id() returns the transaction id. format: $tx+0.$$

Env::Transaction::results()

$tx->results('taskname')

will return an array with the return value(s) of 'run' command executed within 'taskname'. Note: you will always have arrays as return values even if your method will return just a scalar - that will be coated with () by divine intervention

example: in your 'task3::callback' method { my $socket = ($tx->results('ssh_connect'))[1]; close($socket);}

don't forget callbacks are executed in the same order the tasks were registered (like 'run', un-like 'undo').

this lets you chain the results from an earlier task to the current one.

TODO

a lot. consider this module to be in DEV stage altho the currently documented API will not change but more will be added in time (e.g. clerks to control multiple inter-dependent transactions and policies to resolve dependencies)

EXPORT

Env::Transaction exports by default the constants TX_TWO_PHASE_COMMIT and TX_ONE_PHASE_COMMIT. The rest are some sort of perl object-oriented subliminal techniques.

CAVEATS/BUGS

bugs - probably. code is a mess, please rely on pod only when using the module. this is the same with the virgin male to whom you give too much and too fast possey access. he will mess around with a lot of bloodshed and no victims ... but will give you awesome war stories. thats what l.w. made with perl to all virgin perl codewriters.

SEE ALSO

the pyramids.

AUTHOR

adrian ilarion ciobanu, <cia@mud.ro>

COPYRIGHT AND LICENSE

Copyright (C) 2009 by adrian ilarion ciobanu

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.8 or, at your option, any later version of Perl 5 you may have available.