dynflow 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +6 -0
- data/.travis.yml +9 -0
- data/Gemfile +0 -10
- data/MIT-LICENSE +1 -1
- data/README.md +99 -37
- data/Rakefile +2 -6
- data/doc/images/logo.png +0 -0
- data/dynflow.gemspec +10 -1
- data/examples/generate_work_for_daemon.rb +24 -0
- data/examples/orchestrate.rb +121 -0
- data/examples/run_daemon.rb +17 -0
- data/examples/web_console.rb +29 -0
- data/lib/dynflow.rb +27 -6
- data/lib/dynflow/action.rb +185 -77
- data/lib/dynflow/action/cancellable_polling.rb +18 -0
- data/lib/dynflow/action/finalize_phase.rb +18 -0
- data/lib/dynflow/action/flow_phase.rb +44 -0
- data/lib/dynflow/action/format.rb +46 -0
- data/lib/dynflow/action/missing.rb +26 -0
- data/lib/dynflow/action/plan_phase.rb +85 -0
- data/lib/dynflow/action/polling.rb +49 -0
- data/lib/dynflow/action/presenter.rb +51 -0
- data/lib/dynflow/action/progress.rb +62 -0
- data/lib/dynflow/action/run_phase.rb +43 -0
- data/lib/dynflow/action/suspended.rb +21 -0
- data/lib/dynflow/clock.rb +133 -0
- data/lib/dynflow/daemon.rb +29 -0
- data/lib/dynflow/execution_plan.rb +285 -33
- data/lib/dynflow/execution_plan/dependency_graph.rb +29 -0
- data/lib/dynflow/execution_plan/output_reference.rb +52 -0
- data/lib/dynflow/execution_plan/steps.rb +12 -0
- data/lib/dynflow/execution_plan/steps/abstract.rb +121 -0
- data/lib/dynflow/execution_plan/steps/abstract_flow_step.rb +52 -0
- data/lib/dynflow/execution_plan/steps/error.rb +33 -0
- data/lib/dynflow/execution_plan/steps/finalize_step.rb +23 -0
- data/lib/dynflow/execution_plan/steps/plan_step.rb +81 -0
- data/lib/dynflow/execution_plan/steps/run_step.rb +21 -0
- data/lib/dynflow/executors.rb +9 -0
- data/lib/dynflow/executors/abstract.rb +32 -0
- data/lib/dynflow/executors/parallel.rb +88 -0
- data/lib/dynflow/executors/parallel/core.rb +119 -0
- data/lib/dynflow/executors/parallel/execution_plan_manager.rb +120 -0
- data/lib/dynflow/executors/parallel/flow_manager.rb +48 -0
- data/lib/dynflow/executors/parallel/pool.rb +102 -0
- data/lib/dynflow/executors/parallel/running_steps_manager.rb +63 -0
- data/lib/dynflow/executors/parallel/sequence_cursor.rb +97 -0
- data/lib/dynflow/executors/parallel/sequential_manager.rb +81 -0
- data/lib/dynflow/executors/parallel/work_queue.rb +44 -0
- data/lib/dynflow/executors/parallel/worker.rb +30 -0
- data/lib/dynflow/executors/remote_via_socket.rb +38 -0
- data/lib/dynflow/executors/remote_via_socket/core.rb +150 -0
- data/lib/dynflow/flows.rb +13 -0
- data/lib/dynflow/flows/abstract.rb +36 -0
- data/lib/dynflow/flows/abstract_composed.rb +104 -0
- data/lib/dynflow/flows/atom.rb +36 -0
- data/lib/dynflow/flows/concurrence.rb +28 -0
- data/lib/dynflow/flows/sequence.rb +13 -0
- data/lib/dynflow/future.rb +173 -0
- data/lib/dynflow/listeners.rb +7 -0
- data/lib/dynflow/listeners/abstract.rb +13 -0
- data/lib/dynflow/listeners/serialization.rb +41 -0
- data/lib/dynflow/listeners/socket.rb +88 -0
- data/lib/dynflow/logger_adapters.rb +8 -0
- data/lib/dynflow/logger_adapters/abstract.rb +30 -0
- data/lib/dynflow/logger_adapters/delegator.rb +13 -0
- data/lib/dynflow/logger_adapters/formatters.rb +8 -0
- data/lib/dynflow/logger_adapters/formatters/abstract.rb +33 -0
- data/lib/dynflow/logger_adapters/formatters/exception.rb +15 -0
- data/lib/dynflow/logger_adapters/simple.rb +59 -0
- data/lib/dynflow/micro_actor.rb +102 -0
- data/lib/dynflow/persistence.rb +53 -0
- data/lib/dynflow/persistence_adapters.rb +6 -0
- data/lib/dynflow/persistence_adapters/abstract.rb +56 -0
- data/lib/dynflow/persistence_adapters/sequel.rb +160 -0
- data/lib/dynflow/persistence_adapters/sequel_migrations/001_initial.rb +52 -0
- data/lib/dynflow/serializable.rb +66 -0
- data/lib/dynflow/simple_world.rb +18 -0
- data/lib/dynflow/stateful.rb +40 -0
- data/lib/dynflow/testing.rb +32 -0
- data/lib/dynflow/testing/assertions.rb +64 -0
- data/lib/dynflow/testing/dummy_execution_plan.rb +40 -0
- data/lib/dynflow/testing/dummy_executor.rb +29 -0
- data/lib/dynflow/testing/dummy_planned_action.rb +18 -0
- data/lib/dynflow/testing/dummy_step.rb +19 -0
- data/lib/dynflow/testing/dummy_world.rb +33 -0
- data/lib/dynflow/testing/factories.rb +83 -0
- data/lib/dynflow/testing/managed_clock.rb +23 -0
- data/lib/dynflow/testing/mimic.rb +38 -0
- data/lib/dynflow/transaction_adapters.rb +9 -0
- data/lib/dynflow/transaction_adapters/abstract.rb +26 -0
- data/lib/dynflow/transaction_adapters/active_record.rb +27 -0
- data/lib/dynflow/transaction_adapters/none.rb +12 -0
- data/lib/dynflow/version.rb +1 -1
- data/lib/dynflow/web_console.rb +277 -0
- data/lib/dynflow/world.rb +168 -0
- data/test/action_test.rb +89 -11
- data/test/clock_test.rb +59 -0
- data/test/code_workflow_example.rb +382 -0
- data/test/execution_plan_test.rb +195 -64
- data/test/executor_test.rb +692 -0
- data/test/persistance_adapters_test.rb +173 -0
- data/test/test_helper.rb +316 -1
- data/test/testing_test.rb +148 -0
- data/test/web_console_test.rb +38 -0
- data/web/assets/javascripts/application.js +25 -0
- data/web/assets/stylesheets/application.css +101 -0
- data/web/assets/vendor/bootstrap/css/bootstrap-responsive.css +1109 -0
- data/web/assets/vendor/bootstrap/css/bootstrap-responsive.min.css +9 -0
- data/web/assets/vendor/bootstrap/css/bootstrap.css +6167 -0
- data/web/assets/vendor/bootstrap/css/bootstrap.min.css +9 -0
- data/web/assets/vendor/bootstrap/img/glyphicons-halflings-white.png +0 -0
- data/web/assets/vendor/bootstrap/img/glyphicons-halflings.png +0 -0
- data/web/assets/vendor/bootstrap/js/bootstrap.js +2280 -0
- data/web/assets/vendor/bootstrap/js/bootstrap.min.js +6 -0
- data/web/assets/vendor/google-code-prettify/lang-basic.js +3 -0
- data/web/assets/vendor/google-code-prettify/prettify.css +1 -0
- data/web/assets/vendor/google-code-prettify/prettify.js +30 -0
- data/web/assets/vendor/google-code-prettify/run_prettify.js +34 -0
- data/web/assets/vendor/jquery/jquery.js +9807 -0
- data/web/views/flow.erb +19 -0
- data/web/views/flow_step.erb +31 -0
- data/web/views/index.erb +39 -0
- data/web/views/layout.erb +20 -0
- data/web/views/plan_step.erb +11 -0
- data/web/views/show.erb +54 -0
- metadata +250 -11
- data/examples/events.rb +0 -71
- data/examples/workflow.rb +0 -140
- data/lib/dynflow/bus.rb +0 -168
- data/lib/dynflow/dispatcher.rb +0 -36
- data/lib/dynflow/logger.rb +0 -34
- data/lib/dynflow/step.rb +0 -234
- data/test/bus_test.rb +0 -150
data/examples/events.rb
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
# Shows how Dynflow can be used for events architecture: actions are
|
|
2
|
-
# subscribed to an event. When the event is triggered all the
|
|
3
|
-
# subscribed actions are preformed.
|
|
4
|
-
|
|
5
|
-
$:.unshift(File.expand_path('../../lib', __FILE__))
|
|
6
|
-
|
|
7
|
-
require 'dynflow'
|
|
8
|
-
require 'pp'
|
|
9
|
-
|
|
10
|
-
# this is an event that can be triggered.
|
|
11
|
-
# it has an input format so that the interface is given
|
|
12
|
-
# TODO: the validations are turned off right now
|
|
13
|
-
class Click < Dynflow::Action
|
|
14
|
-
input_format do
|
|
15
|
-
param :x, Integer
|
|
16
|
-
param :y, Integer
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
# SayHello subscibes to the event: it's run when the event is triggered
|
|
21
|
-
class SayHello < Dynflow::Action
|
|
22
|
-
|
|
23
|
-
def self.subscribe
|
|
24
|
-
Click
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def run
|
|
28
|
-
puts "Hello World"
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
# we can subscribe more actions to an event
|
|
33
|
-
class SayPosition < Dynflow::Action
|
|
34
|
-
|
|
35
|
-
def self.subscribe
|
|
36
|
-
Click
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def run
|
|
40
|
-
puts "your position is [#{input['x']} - #{input['y']}]"
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
# we can even subscribe to an action that is subscribed to an event
|
|
46
|
-
class SayGoodbye < Dynflow::Action
|
|
47
|
-
|
|
48
|
-
def self.subscribe
|
|
49
|
-
SayPosition
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def run
|
|
53
|
-
puts "Good Bye"
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
Click.trigger('x' => 5, 'y' => 4)
|
|
58
|
-
# gives us:
|
|
59
|
-
# Hello World
|
|
60
|
-
# your position is [5 - 4]
|
|
61
|
-
# Good Bye
|
|
62
|
-
|
|
63
|
-
pp Click.plan('x' => 5, 'y' => 4).actions
|
|
64
|
-
# returns the execution plan for the event (nothing is triggered):
|
|
65
|
-
# [
|
|
66
|
-
# since the event is action as well, it could have a run method
|
|
67
|
-
# [Click: {"x"=>5, "y"=>4} ~> {},
|
|
68
|
-
# SayHello: {"x"=>5, "y"=>4} ~> {},
|
|
69
|
-
# SayPosition: {"x"=>5, "y"=>4} ~> {},
|
|
70
|
-
# SayGoodbye: {"x"=>5, "y"=>4} ~> {}]
|
|
71
|
-
# ]
|
data/examples/workflow.rb
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
# Shows how Dynflow can be used for dynamic workflow definition
|
|
2
|
-
# and execution.
|
|
3
|
-
# In a planning phase of an action, a sub-action can be planned as
|
|
4
|
-
# well.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
$:.unshift(File.expand_path('../../lib', __FILE__))
|
|
8
|
-
|
|
9
|
-
require 'dynflow'
|
|
10
|
-
require 'pp'
|
|
11
|
-
|
|
12
|
-
class Article < Struct.new(:title, :body, :color); end
|
|
13
|
-
|
|
14
|
-
class Publish < Dynflow::Action
|
|
15
|
-
input_format do
|
|
16
|
-
param :title, Integer
|
|
17
|
-
param :body, Integer
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
# plan can take arbitrary arguments. The args are passed from the
|
|
21
|
-
# trigger method.
|
|
22
|
-
def plan(article)
|
|
23
|
-
# we can explicitly plan a subaction
|
|
24
|
-
plan_self 'title' => article.title, 'body' => article.body
|
|
25
|
-
plan_action Review, article
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def run
|
|
29
|
-
puts 'Starting'
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
# after all actions are run, there is a finishing phase. All the
|
|
33
|
-
# actions with +finished+ action defined are called, passing all the
|
|
34
|
-
# performed actions (with inputs and outputs)
|
|
35
|
-
def finalize(outputs)
|
|
36
|
-
printer_action = outputs.find { |o| o.is_a? Print }
|
|
37
|
-
puts "Printer says '#{printer_action.output['message']}'"
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
class Review < Dynflow::Action
|
|
42
|
-
|
|
43
|
-
# the actions can provide an output for the finalizing phase
|
|
44
|
-
output_format do
|
|
45
|
-
param :rating, Integer
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
# the plan method takes the same arguments as the parent action
|
|
49
|
-
def plan(article)
|
|
50
|
-
# in the input attribute the input for the parent action is
|
|
51
|
-
# available
|
|
52
|
-
plan_self input
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
# if no plan method given, the input is the same as the action that
|
|
56
|
-
# triggered it
|
|
57
|
-
def run
|
|
58
|
-
puts "Reviewing #{input['title']}"
|
|
59
|
-
raise "Too Short" if input['body'].size < 6
|
|
60
|
-
output['rating'] = input['body'].size
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def finalize(outputs)
|
|
64
|
-
# +input+ and +output+ attributes are available in the finalizing
|
|
65
|
-
# phase as well.
|
|
66
|
-
puts "The rating was #{output['rating']}"
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
class Print < Dynflow::Action
|
|
72
|
-
|
|
73
|
-
input_format do
|
|
74
|
-
param :title, Integer
|
|
75
|
-
param :body, Integer
|
|
76
|
-
param :color, :boolean
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
output_format do
|
|
80
|
-
param :message, String
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
# if needed, we can subscribe to an action instead of explicitly
|
|
84
|
-
# specifying it in the plan method. Suitable for plugin architecture.
|
|
85
|
-
def self.subscribe
|
|
86
|
-
Review # sucessful review means we can print
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def plan(article)
|
|
90
|
-
plan_self input.merge('color' => article.color)
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def run
|
|
94
|
-
if input['color']
|
|
95
|
-
puts "Printing in color"
|
|
96
|
-
else
|
|
97
|
-
puts "Printing blank&white"
|
|
98
|
-
end
|
|
99
|
-
output['message'] = "Here you are"
|
|
100
|
-
end
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
short_article = Article.new('Short', 'Short', false)
|
|
104
|
-
long_article = Article.new('Long', 'This is long', false)
|
|
105
|
-
colorful_article = Article.new('Long Color', 'This is long in color', true)
|
|
106
|
-
|
|
107
|
-
pp Publish.plan(short_article).actions
|
|
108
|
-
# the expanded workflow is:
|
|
109
|
-
# [
|
|
110
|
-
# Publish: {"title"=>"Short", "body"=>"Short"} ~> {},
|
|
111
|
-
# Review: {"title"=>"Short", "body"=>"Short"} ~> {},
|
|
112
|
-
# Print: {"title"=>"Short", "body"=>"Short", "color"=>false} ~> {}
|
|
113
|
-
# ]
|
|
114
|
-
|
|
115
|
-
begin
|
|
116
|
-
Publish.trigger(short_article)
|
|
117
|
-
rescue => e
|
|
118
|
-
puts e.message
|
|
119
|
-
end
|
|
120
|
-
# Produces:
|
|
121
|
-
# Starting
|
|
122
|
-
# Reviewing Short
|
|
123
|
-
# Too Short
|
|
124
|
-
|
|
125
|
-
Publish.trigger(long_article)
|
|
126
|
-
# Produces:
|
|
127
|
-
# Starting
|
|
128
|
-
# Reviewing Long
|
|
129
|
-
# Printing blank&white
|
|
130
|
-
# Printer says 'Here you are'
|
|
131
|
-
# The rating was 12
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
Publish.trigger(colorful_article)
|
|
135
|
-
# Produces:
|
|
136
|
-
# Starting
|
|
137
|
-
# Reviewing Long Color
|
|
138
|
-
# Printing in color
|
|
139
|
-
# Printer says 'Here you are'
|
|
140
|
-
# The rating was 21
|
data/lib/dynflow/bus.rb
DELETED
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
require 'active_support/inflector'
|
|
2
|
-
require 'forwardable'
|
|
3
|
-
module Dynflow
|
|
4
|
-
class Bus
|
|
5
|
-
|
|
6
|
-
class << self
|
|
7
|
-
extend Forwardable
|
|
8
|
-
|
|
9
|
-
def_delegators :impl, :trigger, :resume, :skip, :preview_execution_plan,
|
|
10
|
-
:persisted_plans, :persisted_plan, :persisted_step
|
|
11
|
-
|
|
12
|
-
def impl
|
|
13
|
-
@impl ||= Bus.new
|
|
14
|
-
end
|
|
15
|
-
attr_writer :impl
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
# Entry point for running an action
|
|
19
|
-
def trigger(action_class, *args)
|
|
20
|
-
execution_plan = nil
|
|
21
|
-
in_transaction_if_possible do
|
|
22
|
-
execution_plan = prepare_execution_plan(action_class, *args)
|
|
23
|
-
rollback_transaction if execution_plan.status == 'error'
|
|
24
|
-
end
|
|
25
|
-
persist_plan_if_possible(execution_plan)
|
|
26
|
-
unless execution_plan.status == 'error'
|
|
27
|
-
execute(execution_plan)
|
|
28
|
-
end
|
|
29
|
-
return execution_plan
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def prepare_execution_plan(action_class, *args)
|
|
33
|
-
action_class.plan(*args)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# execution and finalizaition. Usable for resuming paused plan
|
|
37
|
-
# as well as starting from scratch
|
|
38
|
-
def execute(execution_plan)
|
|
39
|
-
run_execution_plan(execution_plan)
|
|
40
|
-
in_transaction_if_possible do
|
|
41
|
-
unless self.finalize(execution_plan)
|
|
42
|
-
rollback_transaction
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
execution_plan.persist(true)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
alias_method :resume, :execute
|
|
49
|
-
|
|
50
|
-
def skip(step)
|
|
51
|
-
step.status = 'skipped'
|
|
52
|
-
step.persist
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
# return true if everyting worked fine
|
|
56
|
-
def finalize(execution_plan)
|
|
57
|
-
success = true
|
|
58
|
-
if execution_plan.run_steps.any? { |action| ['pending', 'error'].include?(action.status) }
|
|
59
|
-
success = false
|
|
60
|
-
else
|
|
61
|
-
execution_plan.finalize_steps.each(&:replace_references!)
|
|
62
|
-
execution_plan.finalize_steps.each do |step|
|
|
63
|
-
break unless success
|
|
64
|
-
next if %w[skipped].include?(step.status)
|
|
65
|
-
|
|
66
|
-
success = step.catch_errors do
|
|
67
|
-
step.action.finalize(execution_plan.run_steps)
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
if success
|
|
73
|
-
execution_plan.status = 'finished'
|
|
74
|
-
else
|
|
75
|
-
execution_plan.status = 'paused'
|
|
76
|
-
end
|
|
77
|
-
return success
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
# return true if the run phase finished successfully
|
|
81
|
-
def run_execution_plan(execution_plan)
|
|
82
|
-
success = true
|
|
83
|
-
execution_plan.run_steps.map do |step|
|
|
84
|
-
next step if !success || %w[skipped success].include?(step.status)
|
|
85
|
-
step.persist_before_run
|
|
86
|
-
success = step.catch_errors do
|
|
87
|
-
step.output = {}
|
|
88
|
-
step.action.run
|
|
89
|
-
end
|
|
90
|
-
step.persist_after_run
|
|
91
|
-
step
|
|
92
|
-
end
|
|
93
|
-
return success
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
def transaction_driver
|
|
97
|
-
nil
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
def in_transaction_if_possible
|
|
101
|
-
if transaction_driver
|
|
102
|
-
ret = nil
|
|
103
|
-
transaction_driver.transaction do
|
|
104
|
-
ret = yield
|
|
105
|
-
end
|
|
106
|
-
return ret
|
|
107
|
-
else
|
|
108
|
-
return yield
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
def rollback_transaction
|
|
113
|
-
transaction_driver.rollback if transaction_driver
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
def persistence_driver
|
|
118
|
-
nil
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
def persist_plan_if_possible(execution_plan)
|
|
122
|
-
if persistence_driver
|
|
123
|
-
persistence_driver.persist(execution_plan)
|
|
124
|
-
end
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
def persisted_plans(status = nil)
|
|
128
|
-
if persistence_driver
|
|
129
|
-
persistence_driver.persisted_plans(status)
|
|
130
|
-
else
|
|
131
|
-
[]
|
|
132
|
-
end
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
def persisted_plan(persistence_id)
|
|
136
|
-
if persistence_driver
|
|
137
|
-
persistence_driver.persisted_plan(persistence_id)
|
|
138
|
-
end
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def persisted_step(persistence_id)
|
|
142
|
-
if persistence_driver
|
|
143
|
-
persistence_driver.persisted_step(persistence_id)
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
# performs the planning phase of an action, but rollbacks any db
|
|
148
|
-
# changes done in this phase. Returns the resulting execution
|
|
149
|
-
# plan. Suitable for debugging.
|
|
150
|
-
def preview_execution_plan(action_class, *args)
|
|
151
|
-
unless transaction_driver
|
|
152
|
-
raise "Bus doesn't know how to run in transaction"
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
execution_plan = nil
|
|
156
|
-
transaction_driver.transaction do
|
|
157
|
-
execution_plan = prepare_execution_plan(action_class, *args)
|
|
158
|
-
transaction_driver.rollback
|
|
159
|
-
end
|
|
160
|
-
return execution_plan
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
def logger
|
|
164
|
-
@logger ||= Dynflow::Logger.new(self.class)
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
end
|
|
168
|
-
end
|
data/lib/dynflow/dispatcher.rb
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
module Dynflow
|
|
2
|
-
class Dispatcher
|
|
3
|
-
class << self
|
|
4
|
-
def finalizers
|
|
5
|
-
@finalizers ||= Hash.new { |h, k| h[k] = [] }
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
def subscribed_actions(action)
|
|
9
|
-
Action.actions.find_all do |sub_action|
|
|
10
|
-
case sub_action.subscribe
|
|
11
|
-
when Hash
|
|
12
|
-
sub_action.subscribe.keys.include?(action.class)
|
|
13
|
-
when Array
|
|
14
|
-
sub_action.subscribe.include?(action.class)
|
|
15
|
-
else
|
|
16
|
-
sub_action.subscribe == action.class
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def execution_plan_for(action, *plan_args)
|
|
22
|
-
ordered_actions = subscribed_actions(action).sort_by(&:name)
|
|
23
|
-
|
|
24
|
-
execution_plan = ExecutionPlan.new
|
|
25
|
-
ordered_actions.each do |action_class|
|
|
26
|
-
sub_action_plan = action_class.plan(*plan_args) do |sub_action|
|
|
27
|
-
sub_action.input = action.input
|
|
28
|
-
sub_action.from_subscription = true
|
|
29
|
-
end
|
|
30
|
-
execution_plan.concat(sub_action_plan)
|
|
31
|
-
end
|
|
32
|
-
return execution_plan
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
data/lib/dynflow/logger.rb
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
require 'forwardable'
|
|
2
|
-
require 'logger'
|
|
3
|
-
|
|
4
|
-
module Dynflow
|
|
5
|
-
class Logger
|
|
6
|
-
extend Forwardable
|
|
7
|
-
|
|
8
|
-
def_delegators :@impl, :debug, :info, :warn; :error
|
|
9
|
-
|
|
10
|
-
class DummyLogger < ::Logger
|
|
11
|
-
def initialize(identifier)
|
|
12
|
-
super(nil)
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def initialize(identifier, impl = nil)
|
|
18
|
-
@impl = self.class.logger_class.new(identifier)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
class << self
|
|
22
|
-
|
|
23
|
-
def logger_class
|
|
24
|
-
unless @logger_class
|
|
25
|
-
@logger_class ||= DummyLogger
|
|
26
|
-
end
|
|
27
|
-
return @logger_class
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
attr_writer :logger_class
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
end
|
|
34
|
-
end
|