orchestrated 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -5,7 +5,7 @@ The [delayed_job](https://github.com/collectiveidea/delayed_job) Ruby Gem provid
5
5
 
6
6
  By breaking up otherwise serial execution into multiple queued jobs, a program can be made more scalable. This sort of distributed queue-processing architecture has a long and successful history in data processing.
7
7
 
8
- Queuing works well for simple tasks. By simple we mean, the task can be done all at once, in one piece. It has no dependencies on other tasks. This works well for performing a file upload task in the background (to avoid tying up a Ruby virtual machine process/thread). More complex (compound) multi-part tasks, however, do not fit this model. Examples of complex (compound) tasks include:
8
+ Queuing works well for simple tasks. By simple we mean the task can be done all at once, in one piece. It has no dependencies on other tasks. This works well for performing a file upload task in the background (to avoid tying up a Ruby virtual machine process/thread). More complex (compound) multi-part tasks, however, do not fit this model. Examples of complex (compound) tasks include:
9
9
 
10
10
  1. pipelined (multi-step) generation of complex PDF documents
11
11
  2. extract/transfer/load (ETL) jobs that may load thousands of database records
@@ -40,15 +40,15 @@ The API
40
40
  To orchestrate (methods) on your own classes you simply call ```acts_as_orchestrated``` in the class definition like this:
41
41
 
42
42
  ```ruby
43
- class StatementGenerator
43
+ class Xform
44
44
 
45
45
  acts_as_orchestrated
46
46
 
47
- def generate(statement_id)
47
+ def merge(many, one)
48
48
  ...
49
49
  end
50
50
 
51
- def render(statement_id)
51
+ def load(stuff)
52
52
  ...
53
53
  end
54
54
 
@@ -109,7 +109,7 @@ See the completion_spec for examples of how to combine these different prerequis
109
109
  Key Concept: Orchestration State
110
110
  --------------------------------
111
111
 
112
- An orchestration can be in one of six (6) states:
112
+ An orchestration can be in one of a few states:
113
113
 
114
114
  ![Alt text](https://github.com/paydici/orchestrated/raw/master/Orchestrated::Orchestration_state.png 'Orchestration States')
115
115
 
@@ -72,7 +72,7 @@ module Orchestrated
72
72
  notify_dependents_of_completion
73
73
  end
74
74
  def prerequisite_canceled
75
- notify_dependents_of_completion unless prerequisite_associations.without_states('canceled').exists?
75
+ notify_dependents_of_cancellation unless prerequisite_associations.without_states('canceled').exists?
76
76
  end
77
77
  end
78
78
  class OrchestrationCompletionShim < CompletionExpression
@@ -16,11 +16,11 @@ module Orchestrated
16
16
  event :prerequisite_canceled do
17
17
  transition :incomplete => :canceled
18
18
  end
19
- after_transition any => :complete do |orchestration, transition|
20
- orchestration.dependent.prerequisite_complete
19
+ after_transition any => :complete do |dependency, transition|
20
+ dependency.dependent.prerequisite_complete
21
21
  end
22
- after_transition any => :canceled do |orchestration, transition|
23
- orchestration.dependent.prerequisite_canceled
22
+ after_transition any => :canceled do |dependency, transition|
23
+ dependency.dependent.prerequisite_canceled
24
24
  end
25
25
  end
26
26
  end
@@ -1,3 +1,3 @@
1
1
  module Orchestrated
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
data/spec/spec_helper.rb CHANGED
@@ -84,6 +84,7 @@ require 'spec_helper_methods'
84
84
  require 'database_cleaner' # see comments below
85
85
 
86
86
  RSpec.configure do |config|
87
+
87
88
  # This standard Rails approach won't work in this project (which is not
88
89
  # _really_ a Rails app after all.
89
90
  # config.use_transactional_fixtures = true
@@ -107,5 +108,14 @@ RSpec.configure do |config|
107
108
  # --seed 1234
108
109
  config.order = "random"
109
110
 
111
+ # Use color in STDOUT
112
+ config.color_enabled = true
113
+
114
+ # Use color not only in STDOUT but also in pagers and files
115
+ config.tty = true
116
+
117
+ # Use the specified formatter
118
+ config.formatter = :progress # :documentation :progress, :html, :textmate
119
+
110
120
  config.include SpecHelperMethods
111
121
  end
@@ -2,27 +2,42 @@ require 'spec_helper'
2
2
 
3
3
  require 'orchestrated'
4
4
 
5
- shared_examples_for 'cancellation:' do
5
+ shared_context 'cancelling first prerequisite' do
6
6
  before(:each) do
7
- @prerequisite.cancel!
7
+ first_prerequisite.cancel!
8
8
  end
9
+ end
10
+ shared_context 'cancelling all prerequisites' do
11
+ before(:each) do
12
+ first_prerequisite.cancel!
13
+ last_prerequisite.cancel!
14
+ end
15
+ end
16
+ shared_examples_for 'cancellation:' do
9
17
  it 'dependent should be in the "canceled" state' do
10
- expect(@dependent.reload.canceled?).to be_true
18
+ expect(dependent.reload.canceled?).to be_true
19
+ end
20
+ end
21
+ shared_examples_for "cancellation doesn't (cancel):" do
22
+ it 'dependent not should be in the "canceled" state' do
23
+ expect(dependent.reload.canceled?).to be_false
11
24
  end
12
25
  end
13
-
14
26
  shared_examples_for 'cannot cancel:' do
15
- it 'dependent should be in the "canceled" state' do
16
- expect{@prerequisite.cancel!}.to raise_error(StateMachine::InvalidTransition)
27
+ it 'should raise an error when we try to cancel it' do
28
+ expect{@first_prerequisite.cancel!}.to raise_error(StateMachine::InvalidTransition)
17
29
  end
18
30
  end
19
31
 
20
32
  describe 'cancellation' do
33
+ attr_accessor :first_prerequisite, :last_prerequisite, :dependent
34
+ def dependent;@dependent;end
21
35
  context 'directly on an orchestration' do
22
36
  before(:each) do
23
- @prerequisite = @dependent = First.new.orchestrated.do_first_thing(1)
37
+ @first_prerequisite = @dependent = First.new.orchestrated.do_first_thing(1)
24
38
  end
25
39
  context 'that is ready' do
40
+ include_context 'cancelling first prerequisite'
26
41
  it_should_behave_like 'cancellation:'
27
42
  it 'should never subsequently deliver the orchestrated message' do
28
43
  First.any_instance.should_not_receive(:do_first_thing)
@@ -31,36 +46,55 @@ describe 'cancellation' do
31
46
  end
32
47
  context 'that is succeeded' do
33
48
  before(:each) do
34
- @prerequisite.orchestration.state = 'succeeded'
49
+ @first_prerequisite.orchestration.state = 'succeeded'
35
50
  end
36
51
  it_should_behave_like 'cannot cancel:'
37
52
  end
38
53
  context 'that is failed' do
39
54
  before(:each) do
40
- @prerequisite.orchestration.state = 'failed'
55
+ @first_prerequisite.orchestration.state = 'failed'
41
56
  end
42
57
  it_should_behave_like 'cannot cancel:'
43
58
  end
44
59
  context 'that is canceled' do
45
60
  before(:each) do
46
- @prerequisite.orchestration.state = 'canceled'
61
+ @first_prerequisite.orchestration.state = 'canceled'
47
62
  end
48
63
  it_should_behave_like 'cannot cancel:'
49
64
  end
50
65
  end
51
66
  context 'of an orchestration that is depended on directly' do
52
67
  before(:each) do
53
- @dependent = Second.new.orchestrated( @prerequisite = First.new.orchestrated.do_first_thing(1)).do_second_thing(2)
68
+ @dependent = Second.new.orchestrated( @first_prerequisite = First.new.orchestrated.do_first_thing(1)).do_second_thing(2)
54
69
  end
70
+ include_context 'cancelling first prerequisite'
55
71
  it_should_behave_like 'cancellation:'
56
72
  end
57
73
  context 'of an orchestration that is depended on through a LastCompletion' do
58
74
  before(:each) do
59
75
  @dependent = Second.new.orchestrated(
60
76
  Orchestrated::LastCompletion.new <<
61
- (@prerequisite = First.new.orchestrated.do_first_thing(1))
77
+ (@first_prerequisite = First.new.orchestrated.do_first_thing(1))
62
78
  ).do_second_thing(2)
63
79
  end
80
+ include_context 'cancelling first prerequisite'
64
81
  it_should_behave_like 'cancellation:'
65
82
  end
83
+ context 'of an orchestration that is depended on through a FirstCompletion with two prerequisites' do
84
+ before(:each) do
85
+ @dependent = Second.new.orchestrated(
86
+ Orchestrated::FirstCompletion.new <<
87
+ (@first_prerequisite = First.new.orchestrated.do_first_thing(3)) <<
88
+ (@last_prerequisite = First.new.orchestrated.do_first_thing(1))
89
+ ).do_second_thing(2)
90
+ end
91
+ context 'after first prerequisite is canceled' do
92
+ include_context 'cancelling first prerequisite'
93
+ it_should_behave_like "cancellation doesn't (cancel):"
94
+ end
95
+ context 'after last prerequisite is canceled' do
96
+ include_context 'cancelling all prerequisites'
97
+ it_should_behave_like "cancellation:"
98
+ end
99
+ end
66
100
  end
@@ -2,6 +2,16 @@ require 'spec_helper'
2
2
 
3
3
  require 'orchestrated'
4
4
 
5
+
6
+ shared_examples_for 'orchestration accessing prerequisite and dependent' do
7
+ it 'should reach interest at prerequisite' do
8
+ expect(@orchestration.prerequisite).to eq(@interest)
9
+ end
10
+ it 'should reach completion at dependent' do
11
+ expect(@orchestration.dependent).to eq(@completion)
12
+ end
13
+ end
14
+
5
15
  describe Orchestrated do
6
16
  context 'initializing' do
7
17
  it 'should not define orchestrated on Object' do
@@ -14,7 +24,7 @@ describe Orchestrated do
14
24
  expect(First.public_method_defined?(:orchestrated)).to be_true
15
25
  end
16
26
  end
17
- context 'a new orchestrated object' do
27
+ context 'a new object' do
18
28
  let(:f){First.new}
19
29
  context 'responding to messages without orchestration' do
20
30
  let(:result){f.do_first_thing(2)} # 2 is a prime number
@@ -22,6 +32,49 @@ describe Orchestrated do
22
32
  expect(result).to eq(5 * 2)
23
33
  end
24
34
  end
35
+ # I don't trust the has_one associations inside Orchestration to work right with the STI Completion hierarchy
36
+ # after spec'ing this I see that ActiveRecord does indeed qualify the has_one lookup (both of them)
37
+ # with the "type" field yay!
38
+ context 'creating orchestrated' do
39
+ # TODO: reimplement the next three functions as Factory Girl factories!
40
+ def create_orchestration
41
+ Orchestrated::Orchestration.new.tap do |orchestration|
42
+ orchestration.handler = Orchestrated::Orchestration::Handler.new( f, :do_first_thing, [1])
43
+ orchestration.save!
44
+ end
45
+ end
46
+ def create_interest(orchestration, prerequisite=Orchestrated::Complete.new)
47
+ prerequisite.save!
48
+ Orchestrated::OrchestrationInterest.new.tap do |interest|
49
+ interest.prerequisite = prerequisite
50
+ interest.orchestration = orchestration
51
+ interest.save!
52
+ end
53
+ end
54
+ def create_completion(orchestration)
55
+ Orchestrated::OrchestrationCompletion.new.tap do |completion|
56
+ completion.orchestration = @orchestration
57
+ completion.save!
58
+ end
59
+ end
60
+ before(:each) do
61
+ @orchestration = create_orchestration
62
+ end
63
+ context 'with prerequisite created before dependent' do
64
+ before(:each) do
65
+ @interest = create_interest(@orchestration)
66
+ @completion = create_completion(@orchestration)
67
+ end
68
+ it_should_behave_like 'orchestration accessing prerequisite and dependent'
69
+ end
70
+ context 'with dependent created before prerequisite' do
71
+ before(:each) do
72
+ @completion = create_completion(@orchestration)
73
+ @interest = create_interest(@orchestration)
74
+ end
75
+ it_should_behave_like 'orchestration accessing prerequisite and dependent'
76
+ end
77
+ end
25
78
  context 'orchestrating with no prerequisites' do
26
79
  before(:each){@result = f.orchestrated.do_first_thing(2)}
27
80
  after(:each){DJ.clear_all_jobs}
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: orchestrated
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: