empipelines 0.2.1 → 0.2.2

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/README.md CHANGED
@@ -3,7 +3,6 @@
3
3
  ## TODO
4
4
  * Make wiring easier
5
5
  * Example apps
6
- * TerminatorStage should consume message
7
6
  * Control flow for AmqpEventSource
8
7
  * Transaction ID on each message
9
8
  * Evented I/O for IOEventSource
data/Rakefile CHANGED
@@ -116,6 +116,7 @@ task :release => :ci do
116
116
  git tag -a #{gem_file} -m 'Version #{gem_file}'
117
117
  git push origin master
118
118
  git push origin --tags
119
+ gem push pkg/#{gem_file}
119
120
  END
120
121
  end
121
122
 
data/empipelines.gemspec CHANGED
@@ -4,8 +4,8 @@ Gem::Specification.new do |s|
4
4
  s.rubygems_version = '1.3.5'
5
5
  ## Leave these as is they will be modified for you by the rake gemspec task.
6
6
  s.name = 'empipelines'
7
- s.version = '0.2.1'
8
- s.date = '2011-12-21'
7
+ s.version = '0.2.2'
8
+ s.date = '2011-12-23'
9
9
  s.rubyforge_project = 'empipelines'
10
10
 
11
11
  s.summary = "Simple Event Handling Pipeline Architecture for EventMachine"
@@ -37,9 +37,12 @@ Gem::Specification.new do |s|
37
37
  Rakefile
38
38
  empipelines.gemspec
39
39
  functional/consuming_events_from_file_spec.rb
40
+ functional/consuming_events_from_multiple_sources_spec.rb
41
+ functional/consuming_events_from_queue_spec.rb
40
42
  functional/events.dat
41
43
  functional/test_stages.rb
42
44
  lib/empipelines.rb
45
+ lib/empipelines/aggregated_event_source.rb
43
46
  lib/empipelines/amqp_event_source.rb
44
47
  lib/empipelines/batch_event_source.rb
45
48
  lib/empipelines/event_handlers.rb
@@ -49,6 +52,7 @@ Gem::Specification.new do |s|
49
52
  lib/empipelines/message.rb
50
53
  lib/empipelines/periodic_event_source.rb
51
54
  lib/empipelines/pipeline.rb
55
+ unit/empipelines/aggregated_event_source_spec.rb
52
56
  unit/empipelines/amqp_event_source_spec.rb
53
57
  unit/empipelines/batch_event_source_spec.rb
54
58
  unit/empipelines/empty_io_event_source.dat
@@ -10,29 +10,17 @@ module TestStages
10
10
  include EmRunner
11
11
 
12
12
  it 'consumes all events from the file' do
13
- with_em_run do
13
+ with_em_run do
14
14
  pipeline = EmPipelines::Pipeline.new(EM, {:processed => processed}, monitoring, logger)
15
15
 
16
16
  file_name = File.join(File.dirname(__FILE__), 'events.dat')
17
17
  source = EmPipelines::IOEventSource.new(EM, file_name)
18
18
 
19
- stages = [PassthroughStage, PassthroughStage, PassthroughStage, ConsumeStage]
19
+ stages = [PassthroughStage, PassthroughStage, PassthroughStage]
20
20
  event_pipeline = EmPipelines::EventPipeline.new(source, pipeline.for(stages), monitoring)
21
21
 
22
- source.on_finished do |messages|
23
- EM.stop
24
- messages.should have(10).items
25
- messages[0][:payload].should ==("event #0")
26
- messages[1][:payload].should ==("event #1")
27
- messages[2][:payload].should ==("event #2")
28
- messages[3][:payload].should ==("event #3")
29
- messages[4][:payload].should ==("event #4")
30
- messages[5][:payload].should ==("event #5")
31
- messages[6][:payload].should ==("event #6")
32
- messages[7][:payload].should ==("event #7")
33
- messages[8][:payload].should ==("event #8")
34
- messages[9][:payload].should ==("event #9")
35
- messages.each { |m| m.state.should ==(:consumed) }
22
+ source.on_finished do |s|
23
+ EM.stop
36
24
  end
37
25
 
38
26
  event_pipeline.start!
@@ -0,0 +1,31 @@
1
+ require 'eventmachine'
2
+ require 'empipelines'
3
+ require File.join(File.dirname(__FILE__), 'test_stages')
4
+
5
+ module TestStages
6
+ describe 'Consumption of events from multiple sources' do
7
+ let(:monitoring) { stub() }
8
+ let(:logger) { stub(:info => nil, :debug => nil) }
9
+ let (:processed) { {} }
10
+ include EmRunner
11
+
12
+ it 'consumes all events from all sources' do
13
+ pipeline = EmPipelines::Pipeline.new(EM, {:processed => processed}, monitoring, logger)
14
+
15
+ file_name = File.join(File.dirname(__FILE__), 'events.dat')
16
+ num_events_on_file = IO.readlines(file_name).size
17
+ io_source = EmPipelines::IOEventSource.new(EM, file_name)
18
+
19
+ batch = (1...1000).to_a
20
+ batch_name = "my batch!"
21
+ batch_source = EmPipelines::BatchEventSource.new(EM, batch_name, batch)
22
+
23
+ composed_event_source = EmPipelines::AggregatedEventSource.new(EM, batch_source, io_source)
24
+
25
+ composed_event_source.on_finished do |s|
26
+ EM.stop
27
+ s.should ==(composed_event_source)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,32 @@
1
+ require 'eventmachine'
2
+ require 'empipelines'
3
+ require File.join(File.dirname(__FILE__), 'test_stages')
4
+
5
+ module TestStages
6
+ describe 'Consumption of events from a queue' do
7
+ let(:monitoring) { stub() }
8
+ let(:logger) { stub(:info => nil, :debug => nil) }
9
+ let (:processed) { {} }
10
+ include EmRunner
11
+
12
+ it 'consumes all events from the a queue' do
13
+ with_em_run do
14
+ pipeline = EmPipelines::Pipeline.new(EM, {:processed => processed}, monitoring, logger)
15
+
16
+ batch = (1...1000).to_a
17
+ batch_name = "my batch!"
18
+ source = EmPipelines::BatchEventSource.new(EM, batch_name, batch)
19
+
20
+ stages = [PassthroughStage, PassthroughStage, PassthroughStage]
21
+ event_pipeline = EmPipelines::EventPipeline.new(source, pipeline.for(stages), monitoring)
22
+
23
+ source.on_finished do |s|
24
+ EM.stop
25
+ s.should ==(source)
26
+ end
27
+
28
+ event_pipeline.start!
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,10 +1,3 @@
1
- event #0
2
- event #1
3
- event #2
4
- event #3
5
- event #4
6
- event #5
7
- event #6
8
- event #7
9
- event #8
10
- event #9
1
+ 1baa575127c661dfa754a43238b51bdb6adbc0ead0a3b1abec0d45e394ee19f1
2
+ c9730aa998cda290da19a311d19bb91a6aefa3552795dfbd8a2083bf833ba645
3
+ 3fc87b82e170d9e01889537f1dee465e829461178b6eb0ea49b0429e4c75d798
@@ -29,7 +29,7 @@ module TestStages
29
29
  include SomeStage
30
30
 
31
31
  def process(message, callback)
32
- callback.call(message)
32
+ callback.call(message.merge!({}))
33
33
  end
34
34
  end
35
35
 
@@ -0,0 +1,24 @@
1
+ require 'empipelines/event_handlers'
2
+
3
+ module EmPipelines
4
+ class AggregatedEventSource
5
+ include EventHandlers
6
+
7
+ def initialize(em, *event_sources)
8
+ @em, @sources = em, event_sources.flatten
9
+ end
10
+
11
+ def start!
12
+ finished = 0
13
+ @sources.each do |s|
14
+ s.on_event(event_handler)
15
+
16
+ s.on_finished do |*ignored|
17
+ finished += 1
18
+ finished_handler.call(self) if finished == @sources.size
19
+ end
20
+ @em.next_tick { s.start! }
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,6 +1,7 @@
1
1
  require 'json'
2
2
 
3
3
  module EmPipelines
4
+ #this must have a on_finished!
4
5
  class AmqpEventSource
5
6
  def initialize(em, queue, event_name)
6
7
  @em, @queue, @event_name = em, queue, event_name
@@ -5,6 +5,7 @@ module EmPipelines
5
5
  include EventHandlers
6
6
 
7
7
  def initialize(em, list_name, events)
8
+ @num_finalised = 0
8
9
  @em, @list_name, @events = em, list_name,events
9
10
  end
10
11
 
@@ -13,7 +14,7 @@ module EmPipelines
13
14
  check_if_finished
14
15
 
15
16
  message_finished = lambda do |m|
16
- @finalised << m
17
+ @num_finalised += 1
17
18
  check_if_finished
18
19
  end
19
20
 
@@ -33,10 +34,13 @@ module EmPipelines
33
34
 
34
35
  private
35
36
  def check_if_finished
36
- finished = (@finalised.size == @events.size)
37
+ #TODO: can we make this not be based on size?
38
+ #it makes it harder to have streams as event sources (i.e. ranges).
39
+ #this class should only rely on Enumerable methods.
40
+ finished = (@num_finalised == @events.size)
37
41
 
38
42
  if finished and finished_handler
39
- @em.next_tick { finished_handler.call(@finalised) }
43
+ @em.next_tick { finished_handler.call(self) }
40
44
  end
41
45
  end
42
46
  end
@@ -15,7 +15,7 @@ module EmPipelines
15
15
 
16
16
  wrapped_handler = BatchEventSource.new(@em, @file_path, events)
17
17
  wrapped_handler.on_event(event_handler)
18
- wrapped_handler.on_finished(finished_handler)
18
+ wrapped_handler.on_finished { |*ignored| finished_handler.call(self) }
19
19
  wrapped_handler.start!
20
20
  end
21
21
  end
@@ -3,27 +3,28 @@ module EmPipelines
3
3
  attr_reader :state
4
4
 
5
5
  def initialize(base_hash={})
6
- hash!(base_hash)
6
+ backing_hash!(base_hash)
7
7
  created!
8
8
  end
9
9
 
10
10
  def [](key)
11
- hash[key]
11
+ as_hash[key]
12
12
  end
13
13
 
14
14
  def []=(key, value)
15
15
  check_if_mutation_allowed
16
- hash[key] = value
16
+ as_hash[key] = value
17
17
  end
18
18
 
19
19
  def delete(key)
20
20
  check_if_mutation_allowed
21
- hash.delete key
21
+ as_hash.delete key
22
22
  end
23
23
 
24
- def merge(other_hash)
24
+ def merge!(other_hash)
25
25
  check_if_mutation_allowed
26
- Message.new(hash.merge(other_hash))
26
+ backing_hash!(as_hash.merge(other_hash))
27
+ self
27
28
  end
28
29
 
29
30
  def on_consumed(callback=nil, &callback_block)
@@ -56,17 +57,21 @@ module EmPipelines
56
57
  invoke(@rejected_broken_callback)
57
58
  end
58
59
 
59
- def hash
60
+ def as_hash
60
61
  @backing_hash
61
62
  end
63
+
64
+ def payload
65
+ as_hash[:payload]
66
+ end
62
67
 
63
68
  def to_s
64
- "#{self.class.name} state:#{@state} hash:#{hash}"
69
+ "#{self.class.name} state:#{@state} backing_hash:#{as_hash}"
65
70
  end
66
71
 
67
72
  private
68
73
 
69
- def hash!(other)
74
+ def backing_hash!(other)
70
75
  @backing_hash = symbolised(other)
71
76
  end
72
77
 
@@ -1,5 +1,6 @@
1
1
  module EmPipelines
2
2
  class PeriodicEventSource
3
+ #on finish!!!!
3
4
  def initialize(em, name, interval_in_secs, &event_sourcing_code)
4
5
  @em = em
5
6
  @name = name
@@ -1,8 +1,8 @@
1
1
  module EmPipelines
2
2
  class Pipeline
3
3
  class TerminatorStage
4
- def self.notify(ignored, also_ignored = {})
5
- #noop
4
+ def self.notify(message, ignored = {})
5
+ message.consumed!
6
6
  end
7
7
  end
8
8
 
data/lib/empipelines.rb CHANGED
@@ -1,13 +1,16 @@
1
1
  module EmPipelines
2
- VERSION = '0.2.1'
2
+ VERSION = '0.2.2'
3
3
  end
4
4
 
5
+ require 'empipelines/message'
6
+
5
7
  require 'empipelines/event_handlers'
6
8
  require 'empipelines/amqp_event_source'
7
9
  require 'empipelines/batch_event_source'
8
10
  require 'empipelines/io_event_source'
9
- require 'empipelines/event_pipeline'
10
11
  require 'empipelines/list_event_source'
11
- require 'empipelines/message'
12
12
  require 'empipelines/periodic_event_source'
13
+ require 'empipelines/aggregated_event_source'
14
+
15
+ require 'empipelines/event_pipeline'
13
16
  require 'empipelines/pipeline'
@@ -0,0 +1,85 @@
1
+ require 'empipelines/aggregated_event_source'
2
+
3
+ module EmPipelines
4
+ class EventSourceStub
5
+ include EventHandlers
6
+
7
+ def event!(contents)
8
+ raise 'not started' unless @started
9
+ event_handler.call(contents) if event_handler
10
+ end
11
+
12
+ def finish!
13
+ raise 'not started' unless @started
14
+ finished_handler.call([:this, :should, :not, :be, :used])
15
+ end
16
+
17
+ def start!
18
+ @started = true
19
+ end
20
+ end
21
+
22
+ describe AggregatedEventSource do
23
+
24
+ let (:em) do
25
+ em = mock('eventmachine')
26
+ em.stub(:next_tick).and_yield
27
+ em
28
+ end
29
+
30
+ let (:list_name) { "list of stuff" }
31
+
32
+ it 'sends each sends messages from all sources, as they happen, to listeners' do
33
+ source1, source2, source3 = EventSourceStub.new, EventSourceStub.new, EventSourceStub.new
34
+
35
+ aggregated = AggregatedEventSource.new(em, source1, source2, source3)
36
+
37
+ expected = (0..4).map{ |i| stub("Message #{i}") }
38
+ received = []
39
+ aggregated.on_event { |m| received << m}
40
+
41
+ aggregated.start!
42
+
43
+ source1.event! expected[0]
44
+ source2.event! expected[1]
45
+ source2.event! expected[2]
46
+ source3.event! expected[3]
47
+ source1.event! expected[4]
48
+
49
+ received.should ==(expected)
50
+ end
51
+
52
+ it 'calls the finished handler when all sources finished' do
53
+ sources = [EventSourceStub.new, EventSourceStub.new, EventSourceStub.new]
54
+
55
+ aggregated = AggregatedEventSource.new(em, sources)
56
+
57
+ has_finished = [false]
58
+ aggregated.on_finished do |s|
59
+ s.should ==(aggregated)
60
+ has_finished[0] = true
61
+ end
62
+
63
+ aggregated.start!
64
+ sources[2].finish!
65
+ sources[1].finish!
66
+ sources[0].finish!
67
+
68
+ has_finished.first.should be_true
69
+ end
70
+
71
+ it 'does not call the finished handler if a source is still going' do
72
+ sources = [EventSourceStub.new, EventSourceStub.new, EventSourceStub.new]
73
+
74
+ aggregated = AggregatedEventSource.new(em, sources)
75
+
76
+ aggregated.on_finished do |s|
77
+ raise 'should never happen'
78
+ end
79
+
80
+ aggregated.start!
81
+ sources[2].finish!
82
+ sources[0].finish!
83
+ end
84
+ end
85
+ end
@@ -1,6 +1,7 @@
1
1
  require 'empipelines/batch_event_source'
2
2
 
3
3
  module EmPipelines
4
+ ShouldNotBeCalled = lambda { raise 'should not be called' }
4
5
  describe BatchEventSource do
5
6
 
6
7
  let (:em) do
@@ -9,9 +10,9 @@ module EmPipelines
9
10
  em
10
11
  end
11
12
 
12
- let (:list_name) { "list of stuff" }
13
+ let (:list_name) { 'list of stuff' }
13
14
 
14
- it "sends each element on the list as a payload to the listener" do
15
+ it 'sends each element on the list as a payload to the listener' do
15
16
  events = [1,2,3,4,5,6,7,8,9,10]
16
17
  source = BatchEventSource.new(em, list_name, events)
17
18
 
@@ -26,14 +27,15 @@ module EmPipelines
26
27
  received.each{ |i| i[:origin].should == list_name }
27
28
  end
28
29
 
29
- it "calls the batch finished callback when all items were processed" do
30
+ it 'calls the batch finished callback when all items were processed' do
30
31
  events = [1,2,3,4,5,6,7,8,9,10]
31
32
  source = BatchEventSource.new(em, list_name, events)
32
33
 
33
- has_finished = []
34
+ has_finished = [false]
34
35
 
35
- source.on_finished do |messages|
36
- has_finished << messages
36
+ source.on_finished do |s|
37
+ s.should ==(source)
38
+ has_finished[0] = true
37
39
  end
38
40
 
39
41
  source.on_event do |e|
@@ -42,33 +44,30 @@ module EmPipelines
42
44
 
43
45
  source.start!
44
46
 
45
- has_finished.first.map{ |i| i[:payload] }.should ==(events)
47
+ has_finished.first.should be_true
46
48
  end
47
49
 
48
- it "finishes immediately if there are no events to process" do
50
+ it 'finishes immediately if there are no events to process' do
49
51
  source = BatchEventSource.new(em, list_name, [])
50
52
 
51
53
  has_finished = []
52
- source.on_finished do |messages|
54
+ source.on_finished do |s|
55
+ s.should ==(source)
53
56
  has_finished << true
54
57
  end
55
58
 
56
- source.on_event do |e|
57
- raise 'should not be called!'
58
- end
59
+ source.on_event(&ShouldNotBeCalled)
59
60
 
60
61
  source.start!
61
62
 
62
63
  has_finished.first.should be_true
63
64
  end
64
65
 
65
- it "only calls the finished handler if all events were processed" do
66
+ it 'only calls the finished handler if all events were processed' do
66
67
  events = [1,2,3,4,5,6,7,8,9,10]
67
68
  source = BatchEventSource.new(em, list_name, events)
68
69
 
69
- source.on_finished do |messages|
70
- raise "should not be called"
71
- end
70
+ source.on_event(&ShouldNotBeCalled)
72
71
 
73
72
  count = 0
74
73
  source.on_event do |e|
@@ -33,10 +33,11 @@ module EmPipelines
33
33
  it 'calls the finished callback when all messages were processed' do
34
34
  source = IOEventSource.new(em, events_file)
35
35
 
36
- has_finished = []
36
+ has_finished = [false]
37
37
 
38
- source.on_finished do |messages|
39
- has_finished << messages
38
+ source.on_finished do |s|
39
+ s.should ==(source)
40
+ has_finished[0] = true
40
41
  end
41
42
 
42
43
  source.on_event do |e|
@@ -45,15 +46,16 @@ module EmPipelines
45
46
 
46
47
  source.start!
47
48
 
48
- has_finished.first.map{ |i| i[:payload].to_i }.should ==([1,2,3])
49
+ has_finished.first.should be_true
49
50
  end
50
51
 
51
52
  it 'finishes immediately if there are no events to process' do
52
53
  source = IOEventSource.new(em, empty_file)
53
54
 
54
- has_finished = []
55
- source.on_finished do |messages|
56
- has_finished << true
55
+ has_finished = [false]
56
+ source.on_finished do |s|
57
+ s.should ==(source)
58
+ has_finished[0] = true
57
59
  end
58
60
 
59
61
  source.on_event do |e|
@@ -46,12 +46,10 @@ module EmPipelines
46
46
 
47
47
  it "can be merged with a map, symbolising keys" do
48
48
  original = Message.new({'a' => 1})
49
- merged = original.merge({'b' => 2})
49
+ original.merge!({'b' => 2})
50
50
 
51
- original[:b].should be_nil
52
-
53
- merged[:a].should ==(original[:a])
54
- merged[:b].should_not be_nil
51
+ original[:a].should ==(1)
52
+ original[:b].should ==(2)
55
53
  end
56
54
  end
57
55
 
@@ -1,21 +1,45 @@
1
- require "empipelines/pipeline"
1
+ require 'empipelines/pipeline'
2
+
3
+ def msg(some_map)
4
+ EmPipelines:: MessageMock.new(some_map)
5
+ end
2
6
 
3
7
  module EmPipelines
8
+ class MessageMock < EmPipelines::Message
9
+ def consumed!
10
+ raise 'unexpected call'
11
+ end
12
+
13
+ def rejected!
14
+ raise 'unexpected call'
15
+ end
16
+
17
+ def broken!
18
+ raise 'unexpected call'
19
+ end
20
+ end
21
+
4
22
  class AddOne
5
23
  def call(input, &next_stage)
6
- next_stage.call({:data => (input[:data] + 1)})
24
+ next_stage.call(input.merge!({:data => (input[:data] + 1)}))
25
+ end
26
+ end
27
+
28
+ class Passthrough
29
+ def call(input, &next_stage)
30
+ next_stage.call(input)
7
31
  end
8
32
  end
9
33
 
10
34
  class SquareIt
11
35
  def call(input, &next_stage)
12
- next_stage.call({:data => (input[:data] * input[:data])})
36
+ next_stage.call(input.merge!({:data => (input[:data] * input[:data])}))
13
37
  end
14
38
  end
15
39
 
16
40
  class BrokenStage
17
41
  def call(ignore, &ignored_too)
18
- raise "Boo!"
42
+ raise 'Boo!'
19
43
  end
20
44
  end
21
45
 
@@ -27,13 +51,13 @@ module EmPipelines
27
51
 
28
52
  class NeedsAnApple
29
53
  def call(input, &next_stage)
30
- next_stage.call(input.merge({:apple => apple}))
54
+ next_stage.call(input.merge!({:apple => apple}))
31
55
  end
32
56
  end
33
57
 
34
58
  class NeedsAnOrange
35
59
  def call(input, &next_stage)
36
- next_stage.call(input.merge({:orange => orange}))
60
+ next_stage.call(input.merge!({:orange => orange}))
37
61
  end
38
62
  end
39
63
 
@@ -49,7 +73,7 @@ module EmPipelines
49
73
 
50
74
  def call(input, &next_step)
51
75
  @@value = input
52
- next_step.call(self.class)
76
+ next_step.call(input)
53
77
  end
54
78
  end
55
79
 
@@ -72,35 +96,55 @@ module EmPipelines
72
96
 
73
97
  describe Pipeline do
74
98
  let(:logger) {stub(:info => true, :debug => true)}
75
- it "chains the actions using processes" do
99
+
100
+ it 'chains the actions using processes' do
76
101
  event_chain = [AddOne, SquareIt, GlobalHolder]
102
+ a_msg = msg({:data =>1})
103
+ a_msg.should_receive(:consumed!)
104
+
77
105
  pipelines = Pipeline.new(StubSpawner.new, {}, stub('monitoring'), logger)
78
106
  pipeline = pipelines.for(event_chain)
79
- pipeline.notify({:data =>1})
80
- GlobalHolder.held.should eql({:data => 4})
107
+ pipeline.notify(a_msg)
108
+
109
+ GlobalHolder.held[:data].should ==(4)
81
110
  end
82
111
 
83
- it "does not send to the next if last returned nil" do
112
+ it 'does not send to the next if last returned nil' do
84
113
  event_chain = [AddOne, SquareIt, DeadEnd, GlobalHolder]
85
114
  pipelines = Pipeline.new(StubSpawner.new, {}, stub('monitoring'), logger)
86
115
  pipeline = pipelines.for(event_chain)
87
- pipeline.notify({:data => 1})
116
+ pipeline.notify(msg({:data => 1}))
88
117
  GlobalHolder.held.should be_nil
89
118
  end
90
119
 
91
- it "makes all objects in the context object available to stages" do
120
+ it 'makes all objects in the context object available to stages' do
92
121
  event_chain = [NeedsAnApple, NeedsAnOrange, GlobalHolder]
93
122
  pipelines = Pipeline.new(StubSpawner.new, {:apple => :some_apple, :orange => :some_orange}, stub('monitoring'), logger)
123
+ a_msg = msg({})
124
+ a_msg.should_receive(:consumed!)
125
+
94
126
  pipeline = pipelines.for(event_chain)
95
- pipeline.notify({})
96
- GlobalHolder.held.should eql({:apple => :some_apple, :orange => :some_orange})
127
+ pipeline.notify(a_msg)
128
+
129
+ GlobalHolder.held[:apple].should ==(:some_apple)
130
+ GlobalHolder.held[:orange].should ==(:some_orange)
97
131
  end
98
132
 
99
- it "sends exception to the proper handler" do
133
+ it 'sends exception to the proper handler' do
100
134
  monitoring = mock()
101
135
  monitoring.should_receive(:inform_exception!)
102
136
  pipeline = Pipeline.new(StubSpawner.new, {}, monitoring, logger)
103
- pipeline.for([BrokenStage]).notify({})
137
+ pipeline.for([BrokenStage]).notify(msg({}))
138
+ end
139
+
140
+ it 'flags the message as consumed if goest through all stages' do
141
+ event_chain = [Passthrough, Passthrough]
142
+ pipelines = Pipeline.new(StubSpawner.new, {}, stub('monitoring'), logger)
143
+ pipeline = pipelines.for(event_chain)
144
+ a_msg = msg({:data => :whatevah})
145
+ a_msg.should_receive(:consumed!)
146
+
147
+ pipeline.notify(a_msg)
104
148
  end
105
149
  end
106
150
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: empipelines
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2011-12-21 00:00:00.000000000Z
13
+ date: 2011-12-23 00:00:00.000000000Z
14
14
  dependencies: []
15
15
  description: Simple Event Handling Pipeline Architecture for EventMachine
16
16
  email: pcalcado+empipelines@gmail.com
@@ -25,9 +25,12 @@ files:
25
25
  - Rakefile
26
26
  - empipelines.gemspec
27
27
  - functional/consuming_events_from_file_spec.rb
28
+ - functional/consuming_events_from_multiple_sources_spec.rb
29
+ - functional/consuming_events_from_queue_spec.rb
28
30
  - functional/events.dat
29
31
  - functional/test_stages.rb
30
32
  - lib/empipelines.rb
33
+ - lib/empipelines/aggregated_event_source.rb
31
34
  - lib/empipelines/amqp_event_source.rb
32
35
  - lib/empipelines/batch_event_source.rb
33
36
  - lib/empipelines/event_handlers.rb
@@ -37,6 +40,7 @@ files:
37
40
  - lib/empipelines/message.rb
38
41
  - lib/empipelines/periodic_event_source.rb
39
42
  - lib/empipelines/pipeline.rb
43
+ - unit/empipelines/aggregated_event_source_spec.rb
40
44
  - unit/empipelines/amqp_event_source_spec.rb
41
45
  - unit/empipelines/batch_event_source_spec.rb
42
46
  - unit/empipelines/empty_io_event_source.dat
@@ -64,7 +68,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
64
68
  version: '0'
65
69
  segments:
66
70
  - 0
67
- hash: -3827854829014823938
71
+ hash: -530546752871247334
68
72
  required_rubygems_version: !ruby/object:Gem::Requirement
69
73
  none: false
70
74
  requirements: