ruote-amqp 0.9.20 → 0.9.21

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,10 @@
1
+ === 0.9.21 2009-07-13
2
+
3
+ * Depend on ruote-0.9.21 for flexible JSON backends
4
+ * Support for default queues
5
+ * Support for mapping participant names to queue names
6
+ * Plenty of RDOC fixed
7
+
1
8
  === 0.9.20 2009-07-13
2
9
 
3
10
  * 1 major enhancement:
data/Manifest.txt CHANGED
@@ -3,6 +3,7 @@ Manifest.txt
3
3
  PostInstall.txt
4
4
  README.rdoc
5
5
  Rakefile
6
+ TODO.txt
6
7
  lib/ruote-amqp.rb
7
8
  lib/ruote-amqp/listener.rb
8
9
  lib/ruote-amqp/participant.rb
data/README.rdoc CHANGED
@@ -23,13 +23,31 @@ Please review the detailed RDOC in RuoteAMQP::Participant and Ruote::AMQP::Liste
23
23
 
24
24
  == REQUIREMENTS:
25
25
 
26
- * ruote[http://openwfe.rubyforge.org] 0.9.20 or later
26
+ * ruote[http://openwfe.rubyforge.org] 0.9.21 or later
27
27
  * amqp[http://github.com/tmm1/amqp] 0.6.1 or later
28
28
 
29
- NOTE: It might be required that you build the amqp gem yourself
29
+ NOTE: It might be required that you build the amqp gem yourself.
30
+
31
+ ruote 0.9.21 is currently only available to build on your own since John
32
+ Mettraux is working tirelessly to ship ruote 2.0. To build your own ruote
33
+ 0.9.21 gem run these commands:
34
+
35
+ $ git clone git://github.com/jmettraux/ruote.git
36
+ $ cd ruote
37
+ $ rake gem
38
+ $ sudo gem install pkg/ruote-0.9.21.gem
39
+
40
+ Please note that this requires Rubygems 1.3.2 or newer to work
41
+
42
+ If you're using ruote 0.9.20 and would like to use ruote-amqp, you can install
43
+ ruote-amqp-0.9.20, like so:
44
+
45
+ $ sudo gem install ruote-amqp -v 0.9.20
30
46
 
31
47
  == INSTALL:
32
48
 
49
+ Please be sure to have read the requirements section above
50
+
33
51
  * sudo gem install ruote-amqp
34
52
 
35
53
  == DAEMON-KIT:
data/TODO.txt ADDED
@@ -0,0 +1,4 @@
1
+ ruote-amqp TODO
2
+ ===============
3
+
4
+ [ ] Launch processes over AMQP
@@ -6,10 +6,10 @@ module RuoteAMQP
6
6
  #
7
7
  # = AMQP Listeners
8
8
  #
9
- # Used in conjunction with the AMQPParticipant, the AMQPListener
9
+ # Used in conjunction with the RuoteAMQP::Participant, the Listener
10
10
  # subscribes to a specific direct exchange and monitors for
11
11
  # incoming workitems. It expects workitems to arrive serialized as
12
- # JSON (prefered), XML or YAML.
12
+ # JSON.
13
13
  #
14
14
  # == Configuration
15
15
  #
@@ -27,12 +27,12 @@ module RuoteAMQP
27
27
  #
28
28
  # Register the listener with the engine:
29
29
  #
30
- # engine.register_listener( OpenWFE::Extras::AMQPListener )
30
+ # engine.register_listener( RuoteAMQP::Listener )
31
31
  #
32
32
  # The listener leverages the asynchronous nature of the amqp gem,
33
33
  # so no timers are setup when initialized.
34
34
  #
35
- # See the AMQPParticipany docs for information on sending
35
+ # See the RuoteAMQP::Participant docs for information on sending
36
36
  # workitems out to remote participants, and have them send replies
37
37
  # to the correct direct exchange specified in the workitem
38
38
  # attributes.
@@ -40,13 +40,13 @@ module RuoteAMQP
40
40
  class Listener < OpenWFE::Service
41
41
  include OpenWFE::WorkItemListener
42
42
 
43
- # Listening queue
44
- @@queue = 'ruote'
45
-
46
43
  class << self
47
44
 
45
+ # Listening queue
46
+ attr_writer :queue
47
+
48
48
  def queue
49
- @@queue
49
+ @queue ||= 'ruote'
50
50
  end
51
51
 
52
52
  end
@@ -56,7 +56,7 @@ module RuoteAMQP
56
56
  def initialize( service_name, options )
57
57
 
58
58
  if q = options.delete(:queue)
59
- @@queue = q
59
+ self.class.queue = q
60
60
  end
61
61
 
62
62
  super( service_name, options )
@@ -65,9 +65,9 @@ module RuoteAMQP
65
65
  @em_thread = Thread.new { EM.run } unless EM.reactor_running?
66
66
  #end
67
67
 
68
- MQ.queue( @@queue, :durable => true ).subscribe do |message|
68
+ MQ.queue( self.class.queue, :durable => true ).subscribe do |message|
69
69
  workitem = decode_workitem( message )
70
- ldebug { "workitem from '#{@@queue}': #{workitem.inspect}" }
70
+ ldebug { "workitem from '#{self.class.queue}': #{workitem.inspect}" }
71
71
  handle_item( workitem )
72
72
  end
73
73
  end
@@ -85,7 +85,7 @@ module RuoteAMQP
85
85
  def decode_workitem( msg )
86
86
  ldebug { "decoding workitem from: #{msg}" }
87
87
 
88
- hash = JSON.parse(msg)
88
+ hash = OpenWFE::Json.decode(msg)
89
89
  OpenWFE.workitem_from_h( hash )
90
90
  end
91
91
  end
@@ -2,9 +2,9 @@ module RuoteAMQP
2
2
 
3
3
  # = AMQP Participants
4
4
  #
5
- # The AMQPParticipant allows you to send workitems (serialized as
5
+ # The RuoteAMQP::Participant allows you to send workitems (serialized as
6
6
  # JSON) or messages to any AMQP queues right from the process
7
- # definition. When combined with the AMQPListener you can easily
7
+ # definition. When combined with the RuoteAMQP::Listener you can easily
8
8
  # leverage an extremely powerful local/remote participant
9
9
  # combinations.
10
10
  #
@@ -30,12 +30,12 @@ module RuoteAMQP
30
30
  # Setting up the participant
31
31
  #
32
32
  # engine.register_participant(
33
- # :amqp, OpenWFE::Extras::AMQPParticipant )
33
+ # :amqp, RuoteAMQP::Participant )
34
34
  #
35
35
  # Setup a participant that always replies to the engine
36
36
  #
37
37
  # engine.register_participant(
38
- # :amp, OpenWFE::Extras::AMQPParticipant.new(:reply_by_default => true ) )
38
+ # :amqp, RuoteAMQP::Participant.new(:reply_by_default => true ) )
39
39
  #
40
40
  # Sending a message example
41
41
  #
@@ -63,13 +63,41 @@ module RuoteAMQP
63
63
  #
64
64
  # When waiting for a reply it only makes sense to send a workitem.
65
65
  #
66
+ # Keeping things DRY with participant name to queue maps:
67
+ #
68
+ # amqp = RuoteAMQP::Participant.new( :default_queue => 'test' )
69
+ # amqp.map_participant 'george', 'whitehouse'
70
+ # amqp.map_participant 'barak', 'whitehouse'
71
+ # amqp.map_participant 'greenspan', 'treasury'
72
+ #
73
+ # engine.register_participant( :george, amqp )
74
+ # engine.register_participant( :barak, amqp )
75
+ # engine.register_participant( :greespan, amqp )
76
+ # engine.register_participant( :amqp, amqp )
77
+ #
78
+ # class DryAmqProcess0 < OpenWFE::ProcessDefinition
79
+ # cursor :break_if => "${f:economy_recovered}" do
80
+ # # Workitem sent to 'whitehouse' queue
81
+ # george :activity => 'Tank economy'
82
+ #
83
+ # # Workitem sent to 'treasury' queue
84
+ # greenspan :activity => 'Resign'
85
+ #
86
+ # # Workitem sent to 'whitehouse' queue
87
+ # barak :activity => 'Cleanup mess'
88
+ #
89
+ # # Workitem sent to default 'test' queue
90
+ # amqp :activity => 'Notify CNN'
91
+ # end
92
+ # end
93
+ #
66
94
  # == Workitem modifications
67
95
  #
68
96
  # To ease replies, and additional workitem attribute is set:
69
97
  #
70
98
  # 'reply_queue'
71
99
  #
72
- # +reply_queue+ has the name of the queue where the AMQPListener
100
+ # +reply_queue+ has the name of the queue where the RuoteAMQP::Listener
73
101
  # expects replies from remote participants
74
102
  #
75
103
  # == AMQP notes
@@ -87,12 +115,20 @@ module RuoteAMQP
87
115
  # Accepts an options hash with the following keys:
88
116
  #
89
117
  # * :reply_by_default => (bool) false by default
118
+ # * :default_queue => (string) nil by default
90
119
  def initialize( options = {} )
91
120
  ensure_reactor!
92
121
 
93
122
  @options = {
94
- :reply_by_default => false
123
+ :reply_by_default => false,
124
+ :default_queue => nil
95
125
  }.merge( options )
126
+
127
+ @participant_maps = {}
128
+ end
129
+
130
+ def map_participant( name, queue )
131
+ @participant_maps[ name ] = queue
96
132
  end
97
133
 
98
134
  # Process the workitem at hand. By default the workitem will be
@@ -106,7 +142,7 @@ module RuoteAMQP
106
142
  ldebug { "consuming workitem" }
107
143
  ensure_reactor!
108
144
 
109
- if target_queue = workitem.params['queue']
145
+ if target_queue = determine_queue( workitem )
110
146
 
111
147
  q = MQ.queue( target_queue, :durable => true )
112
148
 
@@ -138,12 +174,18 @@ module RuoteAMQP
138
174
  @em_thread.join if @em_thread
139
175
  end
140
176
 
141
- protected
177
+ private
178
+
179
+ def determine_queue( workitem )
180
+ workitem.params['queue'] ||
181
+ @participant_maps[ workitem.participant_name ] ||
182
+ @options[:default_queue]
183
+ end
142
184
 
143
185
  # Encode (and extend) the workitem as JSON
144
186
  def encode_workitem( wi )
145
187
  wi.attributes['reply_queue'] = Listener.queue
146
- JSON.generate( wi.to_h )
188
+ OpenWFE::Json.encode( wi.to_h )
147
189
  end
148
190
 
149
191
  def ensure_reactor!
data/lib/ruote-amqp.rb CHANGED
@@ -5,21 +5,20 @@ begin
5
5
  require 'openwfe'
6
6
  rescue LoadError
7
7
  require 'rubygems'
8
- gem 'ruote', '>= 0.9.20'
8
+ gem 'ruote', '>= 0.9.21'
9
9
  require 'openwfe'
10
10
  end
11
11
  require 'openwfe/version'
12
12
 
13
- if OpenWFE::OPENWFERU_VERSION < '0.9.20'
14
- raise "ruote-amqp requires at least ruote-0.9.20"
13
+ if OpenWFE::OPENWFERU_VERSION < '0.9.21'
14
+ raise "ruote-amqp requires at least ruote-0.9.21"
15
15
  end
16
16
 
17
17
  require 'yaml'
18
- require 'json'
19
18
  require 'mq'
20
19
 
21
20
  module RuoteAMQP
22
- VERSION = '0.9.20'
21
+ VERSION = '0.9.21'
23
22
 
24
23
  autoload 'Participant', 'ruote-amqp/participant'
25
24
  autoload 'Listener', 'ruote-amqp/listener'
@@ -29,17 +29,17 @@ describe RuoteAMQP::Listener do
29
29
 
30
30
  loop do
31
31
  break unless @msg.nil?
32
- sleep 1
32
+ sleep 0.1
33
33
  end
34
34
  end
35
35
  rescue Timeout::Error
36
36
  violated "Timeout waiting for message"
37
37
  end
38
38
 
39
- wi = OpenWFE::InFlowWorkItem.from_h( JSON.parse( @msg ) )
39
+ wi = OpenWFE::InFlowWorkItem.from_h( OpenWFE::Json.decode( @msg ) )
40
40
  wi.attributes['foo'] = "bar"
41
41
 
42
- MQ.queue( wi.attributes['reply_queue'] ).publish( JSON.generate( wi.to_h ) )
42
+ MQ.queue( wi.attributes['reply_queue'] ).publish( OpenWFE::Json.encode( wi.to_h ) )
43
43
 
44
44
  wait( fei )
45
45
 
@@ -27,7 +27,7 @@ describe RuoteAMQP::Participant, :type => :ruote do
27
27
 
28
28
  loop do
29
29
  break unless @msg.nil?
30
- sleep 1
30
+ sleep 0.1
31
31
  end
32
32
  end
33
33
  rescue Timeout::Error
@@ -62,7 +62,7 @@ describe RuoteAMQP::Participant, :type => :ruote do
62
62
 
63
63
  loop do
64
64
  break unless @msg.nil?
65
- sleep 1
65
+ sleep 0.1
66
66
  end
67
67
  end
68
68
  rescue Timeout::Error
@@ -96,7 +96,7 @@ describe RuoteAMQP::Participant, :type => :ruote do
96
96
 
97
97
  loop do
98
98
  break unless @msg.nil?
99
- sleep 1
99
+ sleep 0.1
100
100
  end
101
101
  end
102
102
  rescue Timeout::Error
@@ -105,4 +105,79 @@ describe RuoteAMQP::Participant, :type => :ruote do
105
105
 
106
106
  @msg.should == 'foo'
107
107
  end
108
+
109
+ it "should support a default queue name" do
110
+
111
+ pdef = <<-EOF
112
+ class AmqpParticipant0 < OpenWFE::ProcessDefinition
113
+
114
+ sequence do
115
+ amqp 'reply_anyway' => true
116
+ echo 'done.'
117
+ end
118
+ end
119
+ EOF
120
+
121
+ amqp = RuoteAMQP::Participant.new( :default_queue => 'test5' )
122
+ @engine.register_participant( :amqp, amqp )
123
+
124
+ run_definition( pdef )
125
+
126
+ @tracer.to_s.should == 'done.'
127
+
128
+ begin
129
+ Timeout::timeout(10) do
130
+ @msg = nil
131
+ MQ.queue('test5').subscribe { |msg| @msg = msg }
132
+
133
+ loop do
134
+ break unless @msg.nil?
135
+ sleep 0.1
136
+ end
137
+ end
138
+ rescue Timeout::Error
139
+ violated "Timeout waiting for message"
140
+ end
141
+ end
142
+
143
+ it "should support mapping participant names to queue names" do
144
+ pdef = <<-EOF
145
+ class AmqpParticipant0 < OpenWFE::ProcessDefinition
146
+
147
+ sequence do
148
+ q1
149
+ q2
150
+ amqp
151
+ echo 'done.'
152
+ end
153
+ end
154
+ EOF
155
+
156
+ amqp = RuoteAMQP::Participant.new( :reply_by_default => true, :default_queue => 'test6' )
157
+ amqp.map_participant( 'q1', 'test7' )
158
+ amqp.map_participant( 'q2', 'test8' )
159
+ @engine.register_participant( :amqp, amqp )
160
+ @engine.register_participant( :q1, amqp )
161
+ @engine.register_participant( :q2, amqp )
162
+
163
+ run_definition( pdef )
164
+
165
+ @tracer.to_s.should == 'done.'
166
+
167
+ [ 'test6', 'test7', 'test8' ].each do |q|
168
+ begin
169
+ Timeout::timeout(10) do
170
+ @msg = nil
171
+ MQ.queue( q ).subscribe { |msg| @msg = msg }
172
+
173
+ loop do
174
+ break unless @msg.nil?
175
+ sleep 0.1
176
+ end
177
+ end
178
+ rescue Timeout::Error
179
+ violated "Timeout waiting for message on #{q}"
180
+ end
181
+ end
182
+ end
108
183
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruote-amqp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.20
4
+ version: 0.9.21
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kenneth Kalmer
@@ -42,7 +42,12 @@ dependencies:
42
42
  - !ruby/object:Gem::Version
43
43
  version: 2.3.2
44
44
  version:
45
- description: ruote-amqp provides an AMQP participant/listener pair that allows you to distribute workitems out to AMQP consumers for processing. To learn more about remote participants in ruote please see http://openwfe.rubyforge.org/part.html
45
+ description: |-
46
+ ruote-amqp provides an AMQP participant/listener pair that allows you to
47
+ distribute workitems out to AMQP consumers for processing.
48
+
49
+ To learn more about remote participants in ruote please see
50
+ http://openwfe.rubyforge.org/part.html
46
51
  email:
47
52
  - kenneth.kalmer@gmail.com
48
53
  executables: []
@@ -53,12 +58,14 @@ extra_rdoc_files:
53
58
  - History.txt
54
59
  - Manifest.txt
55
60
  - PostInstall.txt
61
+ - TODO.txt
56
62
  files:
57
63
  - History.txt
58
64
  - Manifest.txt
59
65
  - PostInstall.txt
60
66
  - README.rdoc
61
67
  - Rakefile
68
+ - TODO.txt
62
69
  - lib/ruote-amqp.rb
63
70
  - lib/ruote-amqp/listener.rb
64
71
  - lib/ruote-amqp/participant.rb
@@ -76,6 +83,8 @@ files:
76
83
  - tasks/rspec.rake
77
84
  has_rdoc: true
78
85
  homepage: http://github.com/kennethkalmer/ruote-amqp
86
+ licenses: []
87
+
79
88
  post_install_message: PostInstall.txt
80
89
  rdoc_options:
81
90
  - --main
@@ -97,9 +106,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
97
106
  requirements: []
98
107
 
99
108
  rubyforge_project: ruote-amqp
100
- rubygems_version: 1.3.1
109
+ rubygems_version: 1.3.4
101
110
  signing_key:
102
- specification_version: 2
111
+ specification_version: 3
103
112
  summary: ruote-amqp provides an AMQP participant/listener pair that allows you to distribute workitems out to AMQP consumers for processing
104
113
  test_files: []
105
114