Module: Lev::RoutineNesting
- Defined in:
- lib/lev/routine_nesting.rb
Overview
Manages running of routines inside other routines. In the Lev context, Handlers and Algorithms are routines. A routine and any routines nested inside of it are executed within a single transaction, or depending on the requirements of all the routines, no transaction at all.
Classes that include this module get:
1) a "run" method for running nested routines in a standardized way.
Routines executed through the run method get hooked into the calling
hierarchy.
2) a "runner" accessor which points to the routine which called it. If
runner is nil that means that no other routine called it (some other
code did)
3) a "topmost_runner" which points to the highest routine in the calling
hierarchy (that routine whose 'runner' is nil)
Classes that include this module must:
1) supply a "call" instance method (def call(*args, &block)) that passes
its arguments and block to whatever code inside the class does the work
of the class
Classes that include this module may:
1) Call the class-level "uses_routine" method to indicate which other
routines will be run. Helps set isolation levels, etc. When this
method is used, the provided routine may
2) Set a default transaction isolation level by declaring a class method
named "default_transaction_isolation" that returns an instance of
Lev::TransactionIsolation
Defined Under Namespace
Modules: ClassMethods
Instance Attribute Summary collapse
-
#runner ⇒ Object
readonly
Returns the value of attribute runner.
Class Method Summary collapse
Instance Method Summary collapse
Instance Attribute Details
#runner ⇒ Object
Returns the value of attribute runner.
105 106 107 |
# File 'lib/lev/routine_nesting.rb', line 105 def runner @runner end |
Class Method Details
.included(base) ⇒ Object
40 41 42 |
# File 'lib/lev/routine_nesting.rb', line 40 def self.included(base) base.extend(ClassMethods) end |
Instance Method Details
#in_transaction(options = {}) ⇒ Object
74 75 76 77 78 79 80 81 82 |
# File 'lib/lev/routine_nesting.rb', line 74 def in_transaction(={}) if self != topmost_runner || self.class.transaction_isolation == TransactionIsolation.no_transaction yield else ActiveRecord::Base.isolation_level( self.class.transaction_isolation.symbol ) do ActiveRecord::Base.transaction { yield } end end end |
#run(other_routine, *args, &block) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/lev/routine_nesting.rb', line 84 def run(other_routine, *args, &block) if other_routine.is_a? Symbol nested_routine = self.class.nested_routines[other_routine] if nested_routine.nil? raise IllegalArgument, "Routine symbol #{other_routine} does not point to a registered routine" end other_routine = nested_routine end other_routine = other_routine.new if other_routine.is_a? Class included_modules = other_routine.eigenclass.included_modules raise IllegalArgument, "Can only run another nested routine" \ if !(included_modules.include? Lev::RoutineNesting) other_routine.runner = self other_routine.call(*args, &block) end |