ruote-amqp 2.1.5 → 2.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/{History.txt → CHANGELOG.txt} +18 -4
- data/CREDITS.txt +29 -0
- data/README.rdoc +6 -6
- data/Rakefile +101 -50
- data/TODO.txt +7 -3
- data/lib/ruote-amqp.rb +8 -3
- data/lib/ruote-amqp/launchitem_listener.rb +10 -76
- data/lib/ruote-amqp/participant.rb +154 -99
- data/lib/ruote-amqp/receiver.rb +147 -0
- data/lib/ruote-amqp/version.rb +6 -0
- data/lib/ruote-amqp/workitem_listener.rb +5 -77
- data/ruote-amqp.gemspec +24 -75
- data/spec/launchitem_listener_spec.rb +49 -11
- data/spec/participant_spec.rb +71 -50
- data/spec/receiver_spec.rb +126 -0
- data/spec/ruote_amqp_spec.rb +9 -3
- data/spec/spec_helper.rb +18 -18
- data/spec/support/ruote_helpers.rb +29 -0
- data/{lib/spec → spec/support}/ruote_matchers.rb +14 -9
- data/spec/workitem_listener_spec.rb +30 -15
- metadata +90 -64
- data/.gitignore +0 -6
- data/Manifest.txt +0 -24
- data/lib/spec/ruote.rb +0 -5
- data/lib/spec/ruote_example_group.rb +0 -8
- data/lib/spec/ruote_helpers.rb +0 -27
- data/script/console +0 -10
- data/script/destroy +0 -14
- data/script/generate +0 -14
- data/spec/spec.opts +0 -1
@@ -0,0 +1,147 @@
|
|
1
|
+
|
2
|
+
require 'ruote-amqp'
|
3
|
+
|
4
|
+
|
5
|
+
module RuoteAMQP
|
6
|
+
|
7
|
+
#
|
8
|
+
# = AMQP Receiver
|
9
|
+
#
|
10
|
+
# Used in conjunction with the RuoteAMQP::Participant, the WorkitemListener
|
11
|
+
# subscribes to a specific direct exchange and monitors for
|
12
|
+
# incoming workitems. It expects workitems to arrive serialized as
|
13
|
+
# JSON.
|
14
|
+
#
|
15
|
+
# == Configuration
|
16
|
+
#
|
17
|
+
# AMQP configuration is handled by directly manipulating the values of
|
18
|
+
# the +AMQP.settings+ hash, as provided by the AMQP gem. No
|
19
|
+
# defaults are set by the listener. The only +option+ parsed by
|
20
|
+
# the initializer of the workitem listener is the +queue+ key (Hash
|
21
|
+
# expected). If no +queue+ key is set, the listener will subscribe
|
22
|
+
# to the +ruote_workitems+ direct exchange for workitems, otherwise it will
|
23
|
+
# subscribe to the direct exchange provided.
|
24
|
+
#
|
25
|
+
# == Usage
|
26
|
+
#
|
27
|
+
# Register the engine or storage with the listener:
|
28
|
+
#
|
29
|
+
# RuoteAMQP::Receiver.new(engine_or_storage)
|
30
|
+
#
|
31
|
+
# The workitem listener leverages the asynchronous nature of the amqp gem,
|
32
|
+
# so no timers are setup when initialized.
|
33
|
+
#
|
34
|
+
# == Options
|
35
|
+
#
|
36
|
+
# :queue and :launchitems
|
37
|
+
#
|
38
|
+
# See the RuoteAMQP::Participant docs for information on sending
|
39
|
+
# workitems out to remote participants, and have them send replies
|
40
|
+
# to the correct direct exchange specified in the workitem
|
41
|
+
# attributes.
|
42
|
+
#
|
43
|
+
class Receiver < Ruote::Receiver
|
44
|
+
|
45
|
+
attr_reader :queue
|
46
|
+
|
47
|
+
# Starts a new Receiver
|
48
|
+
#
|
49
|
+
# Two arguments for this method.
|
50
|
+
#
|
51
|
+
# The first oone should be a Ruote::Engine, a Ruote::Storage or
|
52
|
+
# a Ruote::Worker instance.
|
53
|
+
#
|
54
|
+
# The second one is a hash for options. There are two known options :
|
55
|
+
#
|
56
|
+
# :queue for setting the queue on which to listen (defaults to
|
57
|
+
# 'ruote_workitems').
|
58
|
+
#
|
59
|
+
# The :launchitems option :
|
60
|
+
#
|
61
|
+
# :launchitems => true
|
62
|
+
# # the receiver accepts workitems and launchitems
|
63
|
+
# :launchitems => false
|
64
|
+
# # the receiver only accepts workitems
|
65
|
+
# :launchitems => :only
|
66
|
+
# # the receiver only accepts launchitems
|
67
|
+
#
|
68
|
+
def initialize(engine_or_storage, opts={})
|
69
|
+
|
70
|
+
super(engine_or_storage)
|
71
|
+
|
72
|
+
@launchitems = opts[:launchitems]
|
73
|
+
|
74
|
+
@queue =
|
75
|
+
opts[:queue] ||
|
76
|
+
(@launchitems == :only ? 'ruote_launchitems' : 'ruote_workitems')
|
77
|
+
|
78
|
+
RuoteAMQP.start!
|
79
|
+
|
80
|
+
if opts[:unsubscribe]
|
81
|
+
MQ.queue(@queue, :durable => true).unsubscribe
|
82
|
+
sleep 0.300
|
83
|
+
end
|
84
|
+
|
85
|
+
MQ.queue(@queue, :durable => true).subscribe do |message|
|
86
|
+
if AMQP.closing?
|
87
|
+
# do nothing, we're going down
|
88
|
+
else
|
89
|
+
handle(message)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def stop
|
95
|
+
|
96
|
+
RuoteAMQP.stop!
|
97
|
+
end
|
98
|
+
|
99
|
+
# (feel free to overwrite me)
|
100
|
+
#
|
101
|
+
def decode_workitem(msg)
|
102
|
+
|
103
|
+
(Rufus::Json.decode(msg) rescue nil)
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
def handle(msg)
|
109
|
+
|
110
|
+
item = decode_workitem(msg)
|
111
|
+
|
112
|
+
return unless item.is_a?(Hash)
|
113
|
+
|
114
|
+
not_li = ! item.has_key?('definition')
|
115
|
+
|
116
|
+
return if @launchitems == :only && not_li
|
117
|
+
return unless @launchitems || not_li
|
118
|
+
|
119
|
+
if not_li
|
120
|
+
receive(item) # workitem resumes in its process instance
|
121
|
+
else
|
122
|
+
launch(item) # new process instance launch
|
123
|
+
end
|
124
|
+
|
125
|
+
rescue => e
|
126
|
+
# something went wrong
|
127
|
+
# let's simply discard the message
|
128
|
+
$stderr.puts('=' * 80)
|
129
|
+
$stderr.puts(self.class.name)
|
130
|
+
$stderr.puts("couldn't handle incoming message :")
|
131
|
+
$stderr.puts('')
|
132
|
+
$stderr.puts(msg.inspect)
|
133
|
+
$stderr.puts('')
|
134
|
+
$stderr.puts(Rufus::Json.pretty_encode(item)) rescue nil
|
135
|
+
$stderr.puts('')
|
136
|
+
$stderr.puts(e.inspect)
|
137
|
+
$stderr.puts(e.backtrace)
|
138
|
+
$stderr.puts('=' * 80)
|
139
|
+
end
|
140
|
+
|
141
|
+
def launch(hash)
|
142
|
+
|
143
|
+
super(hash['definition'], hash['fields'] || {}, hash['variables'] || {})
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
@@ -1,84 +1,12 @@
|
|
1
|
+
|
1
2
|
module RuoteAMQP
|
2
3
|
|
3
4
|
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
# Used in conjunction with the RuoteAMQP::Participant, the WorkitemListener
|
7
|
-
# subscribes to a specific direct exchange and monitors for
|
8
|
-
# incoming workitems. It expects workitems to arrive serialized as
|
9
|
-
# JSON.
|
10
|
-
#
|
11
|
-
# == Configuration
|
12
|
-
#
|
13
|
-
# AMQP configuration is handled by directly manipulating the values of
|
14
|
-
# the +AMQP.settings+ hash, as provided by the AMQP gem. No
|
15
|
-
# defaults are set by the listener. The only +option+ parsed by
|
16
|
-
# the initializer of the workitem listener is the +queue+ key (Hash
|
17
|
-
# expected). If no +queue+ key is set, the listener will subscribe
|
18
|
-
# to the +ruote_workitems+ direct exchange for workitems, otherwise it will
|
19
|
-
# subscribe to the direct exchange provided.
|
20
|
-
#
|
21
|
-
# The participant requires version 0.6.6 or later of the amqp gem.
|
22
|
-
#
|
23
|
-
# == Usage
|
5
|
+
# Got replaced by RuoteAMQP::Receiver
|
24
6
|
#
|
25
|
-
#
|
7
|
+
# This class is kept for backward compatibility.
|
26
8
|
#
|
27
|
-
|
28
|
-
#
|
29
|
-
# The workitem listener leverages the asynchronous nature of the amqp gem,
|
30
|
-
# so no timers are setup when initialized.
|
31
|
-
#
|
32
|
-
# See the RuoteAMQP::Participant docs for information on sending
|
33
|
-
# workitems out to remote participants, and have them send replies
|
34
|
-
# to the correct direct exchange specified in the workitem
|
35
|
-
# attributes.
|
36
|
-
#
|
37
|
-
class WorkitemListener < Ruote::Receiver
|
38
|
-
|
39
|
-
class << self
|
40
|
-
|
41
|
-
# Listening queue - set this before initialization
|
42
|
-
attr_writer :queue
|
43
|
-
|
44
|
-
def queue
|
45
|
-
@queue ||= 'ruote_workitems'
|
46
|
-
end
|
47
|
-
|
48
|
-
end
|
49
|
-
|
50
|
-
# Starts a new WorkitemListener
|
51
|
-
#
|
52
|
-
# @param [ Ruote::Engine, Ruote::Storage ] A configured ruote engine or storage instance
|
53
|
-
# @param [ String ] An optional queue name
|
54
|
-
def initialize( engine_or_storage, queue = nil )
|
55
|
-
|
56
|
-
@storage = engine_or_storage.respond_to?( :storage ) ? engine_or_storage.storage : engine_or_storage
|
57
|
-
|
58
|
-
self.class.queue = queue if queue
|
59
|
-
|
60
|
-
RuoteAMQP.start!
|
61
|
-
|
62
|
-
MQ.queue( self.class.queue, :durable => true ).subscribe do |message|
|
63
|
-
if AMQP.closing?
|
64
|
-
# Do nothing, we're going down
|
65
|
-
else
|
66
|
-
workitem = decode_workitem( message )
|
67
|
-
reply( workitem )
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def stop
|
73
|
-
RuoteAMQP.stop!
|
74
|
-
end
|
75
|
-
|
76
|
-
private
|
77
|
-
|
78
|
-
# Complicated guesswork that needs to happen here to detect the format
|
79
|
-
def decode_workitem( msg )
|
80
|
-
hash = Rufus::Json.decode( msg )
|
81
|
-
Ruote::Workitem.new( hash )
|
82
|
-
end
|
9
|
+
class WorkitemListener < ::RuoteAMQP::Receiver
|
83
10
|
end
|
84
11
|
end
|
12
|
+
|
data/ruote-amqp.gemspec
CHANGED
@@ -1,83 +1,32 @@
|
|
1
|
-
#
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
-
# -*- encoding: utf-8 -*-
|
1
|
+
# encoding: utf-8
|
5
2
|
|
6
3
|
Gem::Specification.new do |s|
|
7
|
-
s.name = %q{ruote-amqp}
|
8
|
-
s.version = "2.1.5"
|
9
4
|
|
10
|
-
s.
|
11
|
-
s.
|
12
|
-
s.
|
13
|
-
s.
|
14
|
-
s.
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
"Rakefile",
|
28
|
-
"TODO.txt",
|
29
|
-
"lib/ruote-amqp.rb",
|
30
|
-
"lib/ruote-amqp/launchitem_listener.rb",
|
31
|
-
"lib/ruote-amqp/participant.rb",
|
32
|
-
"lib/ruote-amqp/workitem_listener.rb",
|
33
|
-
"lib/spec/ruote.rb",
|
34
|
-
"lib/spec/ruote_example_group.rb",
|
35
|
-
"lib/spec/ruote_helpers.rb",
|
36
|
-
"lib/spec/ruote_matchers.rb",
|
37
|
-
"ruote-amqp.gemspec",
|
38
|
-
"script/console",
|
39
|
-
"script/destroy",
|
40
|
-
"script/generate",
|
41
|
-
"spec/launchitem_listener_spec.rb",
|
42
|
-
"spec/participant_spec.rb",
|
43
|
-
"spec/ruote_amqp_spec.rb",
|
44
|
-
"spec/spec.opts",
|
45
|
-
"spec/spec_helper.rb",
|
46
|
-
"spec/workitem_listener_spec.rb"
|
47
|
-
]
|
48
|
-
s.homepage = %q{http://github.com/kennethkalmer/ruote-amqp}
|
49
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
50
|
-
s.require_paths = ["lib"]
|
51
|
-
s.rubygems_version = %q{1.3.5}
|
52
|
-
s.summary = %q{AMQP participant/listener pair for ruote 2.1}
|
53
|
-
s.test_files = [
|
54
|
-
"spec/launchitem_listener_spec.rb",
|
55
|
-
"spec/participant_spec.rb",
|
56
|
-
"spec/ruote_amqp_spec.rb",
|
57
|
-
"spec/spec_helper.rb",
|
58
|
-
"spec/workitem_listener_spec.rb"
|
5
|
+
s.name = 'ruote-amqp'
|
6
|
+
s.version = File.read('lib/ruote-amqp/version.rb').match(/VERSION = '([^']+)'/)[1]
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = [ 'Kenneth Kalmer', 'John Mettraux' ]
|
9
|
+
s.email = [ 'kenneth.kalmer@gmail.com', 'jmettraux@gmail.com' ]
|
10
|
+
s.homepage = 'http://ruote.rubyforge.org'
|
11
|
+
s.rubyforge_project = 'ruote'
|
12
|
+
s.summary = 'AMQP participant/listener pair for ruote 2.1'
|
13
|
+
s.description = %{
|
14
|
+
AMQP participant/listener pair for ruote 2.1
|
15
|
+
}
|
16
|
+
|
17
|
+
#s.files = `git ls-files`.split("\n")
|
18
|
+
s.files = Dir[
|
19
|
+
'Rakefile',
|
20
|
+
'lib/**/*.rb', 'spec/**/*.rb', 'test/**/*.rb',
|
21
|
+
'*.gemspec', '*.txt', '*.rdoc', '*.md'
|
59
22
|
]
|
60
23
|
|
61
|
-
|
62
|
-
|
63
|
-
|
24
|
+
s.add_runtime_dependency 'amqp', '0.7.0'
|
25
|
+
s.add_runtime_dependency 'ruote', ">= #{s.version}"
|
26
|
+
|
27
|
+
s.add_development_dependency 'rake'
|
28
|
+
s.add_development_dependency 'rspec', ">= 2.2.1"
|
64
29
|
|
65
|
-
|
66
|
-
s.add_runtime_dependency(%q<rufus-json>, [">= 0.1.0"])
|
67
|
-
s.add_runtime_dependency(%q<amqp>, [">= 0.6.6"])
|
68
|
-
s.add_runtime_dependency(%q<ruote>, [">= 2.1.5"])
|
69
|
-
s.add_development_dependency(%q<rspec>, [">= 0"])
|
70
|
-
else
|
71
|
-
s.add_dependency(%q<rufus-json>, [">= 0.1.0"])
|
72
|
-
s.add_dependency(%q<amqp>, [">= 0.6.6"])
|
73
|
-
s.add_dependency(%q<ruote>, [">= 2.1.5"])
|
74
|
-
s.add_dependency(%q<rspec>, [">= 0"])
|
75
|
-
end
|
76
|
-
else
|
77
|
-
s.add_dependency(%q<rufus-json>, [">= 0.1.0"])
|
78
|
-
s.add_dependency(%q<amqp>, [">= 0.6.6"])
|
79
|
-
s.add_dependency(%q<ruote>, [">= 2.1.5"])
|
80
|
-
s.add_dependency(%q<rspec>, [">= 0"])
|
81
|
-
end
|
30
|
+
s.require_path = 'lib'
|
82
31
|
end
|
83
32
|
|
@@ -1,32 +1,70 @@
|
|
1
|
-
|
1
|
+
|
2
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
3
|
+
|
4
|
+
#
|
5
|
+
# NOTE : RuoteAMQP::LaunchitemListener has been depreacted in favour of
|
6
|
+
# RuoteAMQP::Receiver
|
7
|
+
#
|
2
8
|
|
3
9
|
describe RuoteAMQP::LaunchitemListener do
|
4
10
|
|
5
|
-
|
11
|
+
after(:each) do
|
12
|
+
purge_engine
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'launches processes' do
|
16
|
+
|
6
17
|
json = {
|
7
|
-
|
18
|
+
'definition' => %{
|
8
19
|
Ruote.process_definition :name => 'test' do
|
9
20
|
sequence do
|
10
21
|
echo '${f:foo}'
|
11
22
|
end
|
12
23
|
end
|
13
|
-
|
14
|
-
|
15
|
-
"foo" => "bar"
|
16
|
-
}
|
24
|
+
},
|
25
|
+
'fields' => { 'foo' => 'bar' }
|
17
26
|
}.to_json
|
18
27
|
|
19
|
-
RuoteAMQP::LaunchitemListener.new(
|
28
|
+
RuoteAMQP::LaunchitemListener.new(@engine)
|
20
29
|
|
21
|
-
MQ.queue(
|
30
|
+
MQ.queue('ruote_launchitems', :durable => true).publish(json)
|
22
31
|
|
23
32
|
sleep 0.5
|
24
33
|
|
25
34
|
@engine.should_not have_errors
|
26
35
|
@engine.should_not have_remaining_expressions
|
27
36
|
|
28
|
-
@tracer.to_s.should ==
|
37
|
+
@tracer.to_s.should == 'bar'
|
38
|
+
end
|
29
39
|
|
30
|
-
|
40
|
+
it 'discards corrupt process definitions' do
|
41
|
+
|
42
|
+
json = {
|
43
|
+
'definition' => %{
|
44
|
+
I'm a broken process definition
|
45
|
+
},
|
46
|
+
'fields' => { 'foo' => 'bar' }
|
47
|
+
}.to_json
|
48
|
+
|
49
|
+
RuoteAMQP::LaunchitemListener.new(@engine, :unsubscribe => true)
|
50
|
+
|
51
|
+
serr = String.new
|
52
|
+
err = StringIO.new(serr, 'w+')
|
53
|
+
$stderr = err
|
54
|
+
|
55
|
+
MQ.queue('ruote_launchitems', :durable => true).publish(json)
|
56
|
+
|
57
|
+
sleep 0.5
|
58
|
+
|
59
|
+
err.close
|
60
|
+
$stderr = STDERR
|
61
|
+
|
62
|
+
@engine.should_not have_errors
|
63
|
+
@engine.should_not have_remaining_expressions
|
64
|
+
|
65
|
+
@tracer.to_s.should == ''
|
66
|
+
|
67
|
+
serr.should match(/^===/)
|
31
68
|
end
|
32
69
|
end
|
70
|
+
|
data/spec/participant_spec.rb
CHANGED
@@ -1,26 +1,28 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/spec_helper'
|
2
1
|
|
3
|
-
|
2
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
4
3
|
|
5
|
-
|
4
|
+
|
5
|
+
describe RuoteAMQP::ParticipantProxy, :type => :ruote do
|
6
|
+
|
7
|
+
it "supports 'forget' as participant attribute" do
|
6
8
|
|
7
9
|
pdef = ::Ruote.process_definition :name => 'test' do
|
8
10
|
sequence do
|
9
|
-
amqp :queue => 'test1',
|
11
|
+
amqp :queue => 'test1', :forget => true
|
10
12
|
echo 'done.'
|
11
13
|
end
|
12
14
|
end
|
13
15
|
|
14
|
-
@engine.register_participant(
|
16
|
+
@engine.register_participant(:amqp, RuoteAMQP::ParticipantProxy)
|
15
17
|
|
16
|
-
run_definition(
|
18
|
+
run_definition(pdef)
|
17
19
|
|
18
20
|
@tracer.to_s.should == 'done.'
|
19
21
|
|
20
22
|
begin
|
21
23
|
Timeout::timeout(10) do
|
22
24
|
@msg = nil
|
23
|
-
MQ.queue('test1').subscribe { |msg| @msg = msg }
|
25
|
+
MQ.queue('test1', :durable => true).subscribe { |msg| @msg = msg }
|
24
26
|
|
25
27
|
loop do
|
26
28
|
break unless @msg.nil?
|
@@ -34,7 +36,7 @@ describe RuoteAMQP::Participant, :type => :ruote do
|
|
34
36
|
@msg.should match(/^\{.*\}$/) # JSON message by default
|
35
37
|
end
|
36
38
|
|
37
|
-
it "
|
39
|
+
it "supports 'forget' as participant option" do
|
38
40
|
|
39
41
|
pdef = ::Ruote.process_definition :name => 'test' do
|
40
42
|
sequence do
|
@@ -43,17 +45,17 @@ describe RuoteAMQP::Participant, :type => :ruote do
|
|
43
45
|
end
|
44
46
|
end
|
45
47
|
|
46
|
-
|
47
|
-
|
48
|
+
@engine.register_participant(
|
49
|
+
:amqp, RuoteAMQP::ParticipantProxy, 'forget' => true)
|
48
50
|
|
49
|
-
run_definition(
|
51
|
+
run_definition(pdef)
|
50
52
|
|
51
53
|
@tracer.to_s.should == "done."
|
52
54
|
|
53
55
|
begin
|
54
56
|
Timeout::timeout(5) do
|
55
57
|
@msg = nil
|
56
|
-
MQ.queue('test4').subscribe { |msg| @msg = msg }
|
58
|
+
MQ.queue('test4', :durable => true).subscribe { |msg| @msg = msg }
|
57
59
|
|
58
60
|
loop do
|
59
61
|
break unless @msg.nil?
|
@@ -64,28 +66,28 @@ describe RuoteAMQP::Participant, :type => :ruote do
|
|
64
66
|
violated "Timeout waiting for message"
|
65
67
|
end
|
66
68
|
|
67
|
-
@msg.should match(
|
69
|
+
@msg.should match(/^\{.*\}$/) # JSON message by default
|
68
70
|
end
|
69
71
|
|
70
|
-
it "
|
72
|
+
it "supports custom messages instead of workitems" do
|
71
73
|
|
72
74
|
pdef = ::Ruote.process_definition :name => 'test' do
|
73
75
|
sequence do
|
74
|
-
amqp :queue => 'test2', :message => 'foo',
|
76
|
+
amqp :queue => 'test2', :message => 'foo', :forget => true
|
75
77
|
echo 'done.'
|
76
78
|
end
|
77
79
|
end
|
78
80
|
|
79
|
-
@engine.register_participant(
|
81
|
+
@engine.register_participant(:amqp, RuoteAMQP::ParticipantProxy)
|
80
82
|
|
81
|
-
run_definition(
|
83
|
+
run_definition(pdef)
|
82
84
|
|
83
85
|
@tracer.to_s.should == "done."
|
84
86
|
|
85
87
|
begin
|
86
88
|
Timeout::timeout(5) do
|
87
89
|
@msg = nil
|
88
|
-
MQ.queue('test2').subscribe { |msg| @msg = msg }
|
90
|
+
MQ.queue('test2', :durable => true).subscribe { |msg| @msg = msg }
|
89
91
|
|
90
92
|
loop do
|
91
93
|
break unless @msg.nil?
|
@@ -99,26 +101,26 @@ describe RuoteAMQP::Participant, :type => :ruote do
|
|
99
101
|
@msg.should == 'foo'
|
100
102
|
end
|
101
103
|
|
102
|
-
it "
|
104
|
+
it "supports 'queue' as a participant option" do
|
103
105
|
|
104
106
|
pdef = ::Ruote.process_definition :name => 'test' do
|
105
107
|
sequence do
|
106
|
-
amqp
|
108
|
+
amqp :forget => true
|
107
109
|
echo 'done.'
|
108
110
|
end
|
109
111
|
end
|
110
112
|
|
111
|
-
|
112
|
-
|
113
|
+
@engine.register_participant(
|
114
|
+
:amqp, RuoteAMQP::ParticipantProxy, 'queue' => 'test5')
|
113
115
|
|
114
|
-
run_definition(
|
116
|
+
run_definition(pdef)
|
115
117
|
|
116
118
|
@tracer.to_s.should == 'done.'
|
117
119
|
|
118
120
|
begin
|
119
121
|
Timeout::timeout(5) do
|
120
122
|
@msg = nil
|
121
|
-
MQ.queue('test5').subscribe { |msg| @msg = msg }
|
123
|
+
MQ.queue('test5', :durable => true).subscribe { |msg| @msg = msg }
|
122
124
|
|
123
125
|
loop do
|
124
126
|
break unless @msg.nil?
|
@@ -130,42 +132,61 @@ describe RuoteAMQP::Participant, :type => :ruote do
|
|
130
132
|
end
|
131
133
|
end
|
132
134
|
|
133
|
-
it "
|
135
|
+
it "passes 'participant_options' over amqp" do
|
134
136
|
|
135
137
|
pdef = ::Ruote.process_definition :name => 'test' do
|
136
|
-
|
137
|
-
q1
|
138
|
-
q2
|
139
|
-
amqp
|
140
|
-
echo 'done.'
|
141
|
-
end
|
138
|
+
amqp :queue => 'test6', :forget => true
|
142
139
|
end
|
143
140
|
|
144
|
-
|
145
|
-
amqp.map_participant( 'q1', 'test7' )
|
146
|
-
amqp.map_participant( 'q2', 'test8' )
|
147
|
-
@engine.register_participant( :amqp, amqp )
|
148
|
-
@engine.register_participant( :q1, amqp )
|
149
|
-
@engine.register_participant( :q2, amqp )
|
141
|
+
@engine.register_participant(:amqp, RuoteAMQP::ParticipantProxy)
|
150
142
|
|
151
|
-
run_definition(
|
143
|
+
run_definition(pdef)
|
152
144
|
|
153
|
-
|
145
|
+
msg = nil
|
154
146
|
|
155
|
-
|
156
|
-
|
157
|
-
Timeout::timeout(5) do
|
158
|
-
@msg = nil
|
159
|
-
MQ.queue( q ).subscribe { |msg| @msg = msg }
|
147
|
+
begin
|
148
|
+
Timeout::timeout(10) do
|
160
149
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
150
|
+
MQ.queue('test6', :durable => true).subscribe { |m| msg = m }
|
151
|
+
|
152
|
+
loop do
|
153
|
+
break unless msg.nil?
|
154
|
+
sleep 0.1
|
165
155
|
end
|
166
|
-
rescue Timeout::Error
|
167
|
-
violated "Timeout waiting for message on #{q}"
|
168
156
|
end
|
157
|
+
rescue Timeout::Error
|
158
|
+
violated "Timeout waiting for message"
|
169
159
|
end
|
160
|
+
|
161
|
+
wi = Rufus::Json.decode(msg)
|
162
|
+
params = wi['fields']['params']
|
163
|
+
|
164
|
+
params['queue'].should == 'test6'
|
165
|
+
params['forget'].should == true
|
166
|
+
params['participant_options'].should == { 'forget' => false, 'queue' => nil }
|
167
|
+
end
|
168
|
+
|
169
|
+
it "doesn't create 1 queue instance per delivery" do
|
170
|
+
|
171
|
+
pdef = ::Ruote.process_definition do
|
172
|
+
amqp :queue => 'test7', :forget => true
|
173
|
+
end
|
174
|
+
|
175
|
+
mq_count = 0
|
176
|
+
ObjectSpace.each_object(MQ) { |o| mq_count += 1 }
|
177
|
+
|
178
|
+
@engine.register_participant(:amqp, RuoteAMQP::ParticipantProxy)
|
179
|
+
|
180
|
+
10.times do
|
181
|
+
run_definition(pdef)
|
182
|
+
end
|
183
|
+
|
184
|
+
sleep 1
|
185
|
+
|
186
|
+
count = 0
|
187
|
+
ObjectSpace.each_object(MQ) { |o| count += 1 }
|
188
|
+
|
189
|
+
count.should == mq_count + 1
|
170
190
|
end
|
171
191
|
end
|
192
|
+
|