orchestrated 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/orchestrated/base.rb +3 -3
- data/lib/orchestrated/dependency.rb +5 -18
- data/lib/orchestrated/message_delivery.rb +1 -1
- data/lib/orchestrated/orchestration.rb +7 -4
- data/lib/orchestrated/version.rb +1 -1
- data/spec/unit/cancellation_spec.rb +6 -0
- data/spec/unit/completion_spec.rb +1 -1
- data/spec/unit/delayed_job_spec.rb +3 -3
- data/spec/unit/orchestrated_spec.rb +3 -0
- data/spec/unit/rspec_spec.rb +0 -1
- data/spec/unit/static_analysis_spec.rb +3 -3
- metadata +1 -1
data/lib/orchestrated/base.rb
CHANGED
@@ -6,7 +6,7 @@ module Orchestrated
|
|
6
6
|
@target = target
|
7
7
|
end
|
8
8
|
def method_missing(sym, *args)
|
9
|
-
raise 'cannot orchestrate with blocks because they are not portable across processes' if block_given?
|
9
|
+
raise ArgumentError.new('cannot orchestrate with blocks because they are not portable across processes') if block_given?
|
10
10
|
Orchestration.create( @target, sym, args, @prerequisite)
|
11
11
|
end
|
12
12
|
end
|
@@ -25,8 +25,8 @@ module Orchestrated
|
|
25
25
|
unless clazz.method_defined?(method_name)
|
26
26
|
clazz.class_eval "
|
27
27
|
def #{method_name}(prerequisite=Complete.new)
|
28
|
-
raise 'orchestrate does not take a block' if block_given?
|
29
|
-
raise %[cannot use \#{prerequisite.class.name} as a prerequisite] unless
|
28
|
+
raise ArgumentError.new('orchestrate does not take a block') if block_given?
|
29
|
+
raise ArgumentError.new(%[cannot use \#{prerequisite.class.name} as a prerequisite]) unless
|
30
30
|
prerequisite.kind_of?(CompletionExpression)
|
31
31
|
Proxy.new(prerequisite, self)
|
32
32
|
end"
|
@@ -6,7 +6,6 @@ module Orchestrated
|
|
6
6
|
attr_accessible :prerequisite_id
|
7
7
|
belongs_to :prerequisite, :class_name => 'CompletionExpression'
|
8
8
|
belongs_to :dependent, :class_name => 'CompletionExpression'
|
9
|
-
|
10
9
|
before_validation :constrain
|
11
10
|
|
12
11
|
state_machine :initial => :incomplete, :action => :save_avoiding_recursion do
|
@@ -35,23 +34,11 @@ module Orchestrated
|
|
35
34
|
end
|
36
35
|
def _constrain
|
37
36
|
if prerequisite.present?
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
# as part of validation. Rather than loosening the state machine (to allow
|
44
|
-
# e.g. complete=>complete) we explicitly avoid re-submitting events here.
|
45
|
-
prerequisite_completed if prerequisite.complete? && can_prerequisite_completed?
|
46
|
-
prerequisite_canceled if prerequisite.canceled? && can_prerequisite_canceled?
|
47
|
-
else
|
48
|
-
# prerequisite has not changed so our state is already correct
|
49
|
-
if dependent_id_changed?
|
50
|
-
# dependent has been set for the first time—propigate state
|
51
|
-
call_dependent{|d| d.prerequisite_complete} if prerequisite.complete?
|
52
|
-
call_dependent{|d| d.prerequisite_canceled} if prerequisite.canceled?
|
53
|
-
end
|
54
|
-
end
|
37
|
+
# This method can be called more than once in general since it is called
|
38
|
+
# as part of validation. Rather than loosening the state machine (to allow
|
39
|
+
# e.g. complete=>complete) we explicitly avoid re-submitting events here.
|
40
|
+
prerequisite_completed if prerequisite.complete? && can_prerequisite_completed?
|
41
|
+
prerequisite_canceled if prerequisite.canceled? && can_prerequisite_canceled?
|
55
42
|
end
|
56
43
|
true
|
57
44
|
end
|
@@ -3,7 +3,7 @@ module Orchestrated
|
|
3
3
|
attr_accessor :orchestrated, :method_name, :args, :orchestration_id
|
4
4
|
|
5
5
|
def initialize(orchestrated, method_name, args, orchestration_id)
|
6
|
-
raise 'all arguments to MessageDelivery constructor are required' unless
|
6
|
+
raise ArgumentError.new('all arguments to MessageDelivery constructor are required') unless
|
7
7
|
orchestrated and method_name and args and orchestration_id
|
8
8
|
self.orchestrated = orchestrated
|
9
9
|
self.method_name = method_name
|
@@ -55,11 +55,12 @@ module Orchestrated
|
|
55
55
|
transition [:waiting, :ready] => :canceled
|
56
56
|
end
|
57
57
|
|
58
|
-
|
58
|
+
# a before (rather than an after) so that if we change state it'll be saved (piggybacked)
|
59
|
+
before_transition any => :ready do |orchestration, transition|
|
59
60
|
orchestration.enqueue
|
60
61
|
end
|
61
62
|
|
62
|
-
|
63
|
+
before_transition :ready => :canceled do |orchestration, transition|
|
63
64
|
orchestration.dequeue
|
64
65
|
end
|
65
66
|
|
@@ -76,7 +77,7 @@ module Orchestrated
|
|
76
77
|
# Actually creates a completion (wrapper). Not _exactly_ an orchestration—ssh…
|
77
78
|
def self.create( value, sym, args, prerequisite)
|
78
79
|
# wee! static analysis FTW!
|
79
|
-
raise 'prerequisite can never be complete' if prerequisite.never_complete?
|
80
|
+
raise ArgumentError.new('prerequisite can never be complete') if prerequisite.never_complete?
|
80
81
|
prerequisite.save!
|
81
82
|
OrchestrationCompletion.new.tap do |completion|
|
82
83
|
completion.orchestration = new.tap do |orchestration|
|
@@ -87,6 +88,8 @@ module Orchestrated
|
|
87
88
|
interest.orchestration = orchestration
|
88
89
|
interest.save!
|
89
90
|
end # interest
|
91
|
+
# interest linkage can often change orchestration state so we have to reload here
|
92
|
+
orchestration.reload
|
90
93
|
end # orchestration
|
91
94
|
completion.save!
|
92
95
|
end # completion
|
@@ -97,7 +100,7 @@ module Orchestrated
|
|
97
100
|
end
|
98
101
|
|
99
102
|
def dequeue
|
100
|
-
delayed_job.destroy
|
103
|
+
self.delayed_job.destroy
|
101
104
|
end
|
102
105
|
|
103
106
|
end
|
data/lib/orchestrated/version.rb
CHANGED
@@ -36,9 +36,15 @@ describe 'cancellation' do
|
|
36
36
|
before(:each) do
|
37
37
|
@first_prerequisite = @dependent = First.new.orchestrated.do_first_thing(1)
|
38
38
|
end
|
39
|
+
it 'should be ready' do
|
40
|
+
expect(@dependent.orchestration.state).to eq('ready')
|
41
|
+
end
|
39
42
|
context 'that is ready' do
|
40
43
|
include_context 'cancelling first prerequisite'
|
41
44
|
it_should_behave_like 'cancellation:'
|
45
|
+
it 'should have no work queued' do
|
46
|
+
expect(DJ.job_count).to eq(0)
|
47
|
+
end
|
42
48
|
it 'should never subsequently deliver the orchestrated message' do
|
43
49
|
First.any_instance.should_not_receive(:do_first_thing)
|
44
50
|
DJ.work(1)
|
@@ -25,7 +25,7 @@ describe Orchestrated::CompletionExpression do
|
|
25
25
|
end
|
26
26
|
context 'Incomplete' do
|
27
27
|
it 'should immediately raise an error' do
|
28
|
-
expect{First.new.orchestrated(Orchestrated::Incomplete.new).do_first_thing(12)}.to raise_error
|
28
|
+
expect{First.new.orchestrated(Orchestrated::Incomplete.new).do_first_thing(12)}.to raise_error(ArgumentError)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
context 'OrchestrationCompletion' do
|
@@ -84,6 +84,9 @@ describe Orchestrated do
|
|
84
84
|
it 'should return an Orchestration object' do
|
85
85
|
expect(@result).to be_kind_of(Orchestrated::CompletionExpression)
|
86
86
|
end
|
87
|
+
it 'should be ready' do
|
88
|
+
expect(@result.orchestration.state).to eq('ready')
|
89
|
+
end
|
87
90
|
end
|
88
91
|
end
|
89
92
|
context 'invocation' do
|
data/spec/unit/rspec_spec.rb
CHANGED
@@ -8,13 +8,13 @@ describe 'performing static analysis' do
|
|
8
8
|
context 'that is empty' do
|
9
9
|
# chose this behavior to align with Ruby Enumerable#any?
|
10
10
|
it 'should raise an error since it can never be complete' do
|
11
|
-
expect{Second.new.orchestrated(completion).do_second_thing(5)}.to raise_error
|
11
|
+
expect{Second.new.orchestrated(completion).do_second_thing(5)}.to raise_error(ArgumentError)
|
12
12
|
end
|
13
13
|
end
|
14
14
|
context 'that contains only (static) Incompletes' do
|
15
15
|
before(:each){completion<<Orchestrated::Incomplete.new}
|
16
16
|
it 'should raise an error since it can never be complete' do
|
17
|
-
expect{Second.new.orchestrated(completion).do_second_thing(5)}.to raise_error
|
17
|
+
expect{Second.new.orchestrated(completion).do_second_thing(5)}.to raise_error(ArgumentError)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
context 'that directly containins a (static) Complete' do
|
@@ -41,7 +41,7 @@ describe 'performing static analysis' do
|
|
41
41
|
context 'that directly contains a (static) Incomplete' do
|
42
42
|
before(:each){completion<<Orchestrated::Incomplete.new}
|
43
43
|
it 'should raise an error since it can never be complete' do
|
44
|
-
expect{Second.new.orchestrated(completion).do_second_thing(5)}.to raise_error
|
44
|
+
expect{Second.new.orchestrated(completion).do_second_thing(5)}.to raise_error(ArgumentError)
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|