ruote-amqp 2.1.5 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,22 +1,36 @@
1
- === 2.0.0 (WIP)
1
+
2
+ = ruote-amqp
3
+
4
+
5
+ == ruote-amqp - 2.2.0 released 2011/03/01
6
+
7
+ - receiver : exposing #decode_workitem for overwriting
8
+ - options[:queue] patch by Mario Camou
9
+ - :durable path by belucid
10
+ - 1 MQ per dispatch thread 'leak' fix. Thanks weifeng365
11
+ - RuoteAMQP::Participant --> RuoteAMQP::ParticipantProxy
12
+
13
+
14
+ == 2.0.0 not released
2
15
 
3
16
  * Compatible with ruote 2.0
4
17
  * Thanks to John Mettraux (http://github.com/jmettraux/ruote-amqp)
5
18
  * Thanks to Jason & Jordan (http://github.com/asm/ruote-amqp)
6
19
  * Thanks to Charles Magid (http://github.com/ChasManRors/ruote-amqp)
7
20
 
8
- === 0.9.21.1 2009-08-03
21
+ == 0.9.21.1 2009-08-03
9
22
 
10
23
  * Switch to using persistent AMQP messages by default
11
24
 
12
- === 0.9.21 2009-07-13
25
+ == 0.9.21 2009-07-13
13
26
 
14
27
  * Depend on ruote-0.9.21 for flexible JSON backends
15
28
  * Support for default queues
16
29
  * Support for mapping participant names to queue names
17
30
  * Plenty of RDOC fixed
18
31
 
19
- === 0.9.20 2009-07-13
32
+ == 0.9.20 2009-07-13
20
33
 
21
34
  * 1 major enhancement:
22
35
  * Initial release
36
+
data/CREDITS.txt ADDED
@@ -0,0 +1,29 @@
1
+
2
+ = CREDITS
3
+
4
+ (probably incomplete, don't hesitate to tell us if a mention is missing)
5
+
6
+
7
+ == AUTHORS
8
+
9
+ * Kenneth Kalmer - http://www.opensourcery.co.za/
10
+ * John Mettraux - https://github.com/jmettraux
11
+
12
+
13
+ == CONTRIBUTORS
14
+
15
+ * Mario Camou
16
+ * Sean Johnson - https://github.com/belucid
17
+ * Victor Liu - https://github.com/pennymax
18
+ * weifeng - https://github.com/weifeng365
19
+ * David Greaves - https://github.com/lbt
20
+ * Hartog C. de Mik - https://github.com/coffeeaddict
21
+ * Torsten Schoenebaum - https://github.com/tosch
22
+ * Jordan Ritter - https://github.com/jpr5
23
+ * Charles Magid - https://github.com/ChasManRors
24
+ * Marc Mauger - https://github.com/simianarmy
25
+ * Jason - https://github.com/asm
26
+
27
+
28
+ == FEEDBACK
29
+
data/README.rdoc CHANGED
@@ -1,3 +1,4 @@
1
+
1
2
  = ruote-amqp
2
3
 
3
4
  * http://github.com/kennethkalmer/ruote-amqp
@@ -16,7 +17,7 @@ http://ruote.rubyforge.org/part_implementations.html
16
17
  == FEATURES/PROBLEMS:
17
18
 
18
19
  * Flexible participant for sending workitems
19
- * Flexible listener for receiving replies
20
+ * Flexible receiver for receiving replies
20
21
  * Flexible launch item listener for launching processes over AMQP
21
22
  * Fully evented (thanks to the amqp gem)
22
23
 
@@ -26,9 +27,8 @@ Please review the rdoc in RuoteAMQP::Participant and Ruote::AMQP::Listener
26
27
 
27
28
  == REQUIREMENTS:
28
29
 
29
- * ruote[http://ruote.rubyforge.org] 2.1.4 or later
30
- * amqp[http://github.com/tmm1/amqp] 0.6.6 or later
31
- * rufus-json[http://github.com/jmettraux/rufus-json] 0.1.0 or later
30
+ * ruote[http://ruote.rubyforge.org] 2.2.0 or later
31
+ * amqp[http://github.com/tmm1/amqp] 0.6.7 or later
32
32
  * rabbitmq[http://www.rabbitmq.com/] 1.6.0 or later
33
33
 
34
34
  == INSTALL:
@@ -40,7 +40,7 @@ Please be sure to have read the requirements section above
40
40
  == TESTS:
41
41
 
42
42
  To run the tests you need the following requirements met, or the testing environment
43
- will fail horribly.
43
+ will fail horribly (or simply get stuck without output).
44
44
 
45
45
  === RabbitMQ vhost
46
46
 
@@ -69,7 +69,7 @@ DaemonKit doesn't currently support ruote 2.1, support is forthcoming.
69
69
 
70
70
  (The MIT License)
71
71
 
72
- Copyright (c) 2010 Kenneth Kalmer
72
+ Copyright (c) 2010-2011 Kenneth Kalmer
73
73
 
74
74
  Permission is hereby granted, free of charge, to any person obtaining
75
75
  a copy of this software and associated documentation files (the
data/Rakefile CHANGED
@@ -1,50 +1,101 @@
1
- require 'rubygems'
2
- require 'rake'
3
-
4
- require 'lib/ruote-amqp'
5
-
6
- begin
7
- require 'jeweler'
8
- Jeweler::Tasks.new do |gemspec|
9
- gemspec.name = 'ruote-amqp'
10
- gemspec.version = RuoteAMQP::VERSION
11
- gemspec.summary = 'AMQP participant/listener pair for ruote 2.1'
12
- gemspec.email = 'kenneth.kalmer@gmail.com'
13
- gemspec.homepage = 'http://github.com/kennethkalmer/ruote-amqp'
14
- gemspec.authors = ['kenneth.kalmer@gmail.com']
15
- gemspec.extra_rdoc_files.include '*.txt'
16
-
17
- gemspec.add_dependency 'rufus-json', '>= 0.1.0'
18
- gemspec.add_dependency 'amqp', '>= 0.6.6'
19
- gemspec.add_dependency 'ruote', '>= 2.1.5'
20
- gemspec.add_development_dependency 'rspec'
21
- end
22
- Jeweler::GemcutterTasks.new
23
- rescue LoadError
24
- puts "Jeweler not available. Install it with 'gem install jeweler'"
25
- end
26
-
27
- require 'spec/rake/spectask'
28
- Spec::Rake::SpecTask.new(:spec) do |spec|
29
- spec.libs << 'lib' << 'spec'
30
- spec.spec_files = FileList['spec/**/*_spec.rb']
31
- end
32
-
33
- Spec::Rake::SpecTask.new(:rcov) do |spec|
34
- spec.libs << 'lib' << 'spec'
35
- spec.pattern = 'spec/**/*_spec.rb'
36
- spec.rcov = true
37
- end
38
-
39
- task :spec #=> :check_dependencies
40
-
41
- task :default => :spec
42
-
43
- begin
44
- require 'yard'
45
- YARD::Rake::YardocTask.new
46
- rescue LoadError
47
- task :yardoc do
48
- abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
49
- end
50
- end
1
+
2
+ $:.unshift('.') # 1.9.2
3
+
4
+ require 'rubygems'
5
+ require 'rubygems/user_interaction' if Gem::RubyGemsVersion == '1.5.0'
6
+
7
+ require 'rake'
8
+ require 'rake/clean'
9
+ require 'rake/rdoctask'
10
+
11
+
12
+ #
13
+ # clean
14
+
15
+ CLEAN.include('pkg', 'rdoc')
16
+
17
+
18
+ #
19
+ # test / spec
20
+
21
+ task :spec do
22
+
23
+ sh 'rspec spec/'
24
+ end
25
+
26
+ task :test => [ :spec ]
27
+ task :default => [ :spec ]
28
+
29
+
30
+ #
31
+ # gem
32
+
33
+ GEMSPEC_FILE = Dir['*.gemspec'].first
34
+ GEMSPEC = eval(File.read(GEMSPEC_FILE))
35
+ GEMSPEC.validate
36
+
37
+
38
+ desc %{
39
+ builds the gem and places it in pkg/
40
+ }
41
+ task :build do
42
+
43
+ sh "gem build #{GEMSPEC_FILE}"
44
+ sh "mkdir pkg" rescue nil
45
+ sh "mv #{GEMSPEC.name}-#{GEMSPEC.version}.gem pkg/"
46
+ end
47
+
48
+ desc %{
49
+ builds the gem and pushes it to rubygems.org
50
+ }
51
+ task :push => :build do
52
+
53
+ sh "gem push pkg/#{GEMSPEC.name}-#{GEMSPEC.version}.gem"
54
+ end
55
+
56
+
57
+ #
58
+ # rabbitmq preparation
59
+
60
+ desc %{
61
+ prepare RabbitMQ (vhost, user, perms)
62
+ }
63
+ task :prepare do
64
+
65
+ sh "rabbitmqctl add_vhost ruote-test"
66
+ sh "rabbitmqctl add_user ruote ruote"
67
+ sh "rabbitmqctl set_permissions -p ruote-test ruote '.*' '.*' '.*'"
68
+ end
69
+
70
+
71
+ #
72
+ # rdoc
73
+ #
74
+ # make sure to have rdoc 2.5.x to run that
75
+
76
+ Rake::RDocTask.new do |rd|
77
+
78
+ rd.main = 'README.rdoc'
79
+ rd.rdoc_dir = 'rdoc'
80
+
81
+ rd.rdoc_files.include(
82
+ 'README.rdoc', 'CHANGELOG.txt', 'CREDITS.txt', 'lib/**/*.rb')
83
+
84
+ rd.title = "#{GEMSPEC.name} #{GEMSPEC.version}"
85
+ end
86
+
87
+
88
+ #
89
+ # upload_rdoc
90
+
91
+ desc %{
92
+ upload the rdoc to rubyforge
93
+ }
94
+ task :upload_rdoc => [ :clean, :rdoc ] do
95
+
96
+ account = 'jmettraux@rubyforge.org'
97
+ webdir = '/var/www/gforge-projects/ruote'
98
+
99
+ sh "rsync -azv -e ssh rdoc/#{GEMSPEC.name}_rdoc #{account}:#{webdir}/"
100
+ end
101
+
data/TODO.txt CHANGED
@@ -1,4 +1,8 @@
1
- ruote-amqp TODO
2
- ===============
3
1
 
4
- [ ] Launch processes over AMQP
2
+ [o] Launch processes over AMQP (LaunchitemListener)
3
+ [o] Receiver
4
+ [o] ParticipantProxy ?
5
+
6
+ [ ] have a class method ParticipantProxy.stop_all ?
7
+ [ ] use Ruote::Workitem #as_json and #from_json(s)
8
+
data/lib/ruote-amqp.rb CHANGED
@@ -1,5 +1,10 @@
1
+
1
2
  require 'mq'
2
3
 
4
+ require 'ruote-amqp/version'
5
+
6
+
7
+ #
3
8
  # AMQP participant and listener pair for ruote.
4
9
  #
5
10
  # == Documentation
@@ -15,9 +20,9 @@ require 'mq'
15
20
  #
16
21
  module RuoteAMQP
17
22
 
18
- VERSION = '2.1.5'
23
+ autoload 'ParticipantProxy', 'ruote-amqp/participant'
19
24
 
20
- autoload 'Participant', 'ruote-amqp/participant'
25
+ autoload 'Receiver', 'ruote-amqp/receiver'
21
26
  autoload 'WorkitemListener', 'ruote-amqp/workitem_listener'
22
27
  autoload 'LaunchitemListener', 'ruote-amqp/launchitem_listener'
23
28
 
@@ -70,6 +75,6 @@ module RuoteAMQP
70
75
  Thread.main[:ruote_amqp_connection].join
71
76
  Thread.main[:ruote_amqp_started] = false
72
77
  end
73
-
74
78
  end
75
79
  end
80
+
@@ -1,88 +1,22 @@
1
+
1
2
  module RuoteAMQP
2
3
 
3
- # = AMQP Launchitem Listener
4
- #
5
- # Used on its own, the RuoteAMQP::LaunchitemListener provides the engine with
6
- # a way to launch process definitions over an AMQP direct exchange.
7
- #
8
- # == Message Format
9
- #
10
- # The LaunchitemListener expects JSON formatted messages that look like this:
11
- #
12
- # {
13
- # "definition" : "process definition",
14
- # "fields" : { "key" : "value" },
15
- # "variables" : { "key" : "value" }
16
- # }
17
- #
18
- # The definition key is a complete string representation of a business process.
19
- #
20
- # == Configuration
21
4
  #
22
- # AMQP configuration is handled by directly manipulating the values of the
23
- # +AMQP.settings+ hash, as provided by the AMQP gem. No defaults are set by
24
- # the listener. The only +option+ parsed by the initializer is the +queue+
25
- # key (in the optional hash). If no +queue+ key is provided, the listener
26
- # will subscribe to the +ruote_launchitems+ direct exchange for launchitems.
5
+ # Got replaced by RuoteAMQP::Receiver
27
6
  #
28
- # The listener requires version 0.6.6 or later of the amqp gem.
7
+ # This class is kept for backward compatibility.
29
8
  #
30
- # == Usage
31
- #
32
- # Register the engine with the listener:
33
- #
34
- # RuoteAMQP::LaunchitemListener.new( engine_instance )
35
- #
36
- # The workitem listener leverages the asynchronous nature of the amqp gem,
37
- # so no timers are setup when initialized.
38
- class LaunchitemListener < Ruote::Receiver
39
-
40
- class << self
41
-
42
- # Listening queue - set this before initialization
43
- attr_writer :queue
44
-
45
- def queue
46
- @queue ||= 'ruote_launchitems'
47
- end
48
-
49
- end
9
+ class LaunchitemListener < ::RuoteAMQP::Receiver
50
10
 
51
11
  # Start a new LaunchItem listener
52
12
  #
53
- # @param [ Ruote::Engine ] An instance of a ruote engine
54
- # @param [ String ] Optional queue name
55
- def initialize( engine, queue = nil )
56
-
57
- self.class.queue = queue if queue
58
-
59
- RuoteAMQP.start!
60
-
61
- MQ.queue( self.class.queue, :durable => true ).subscribe do |message|
62
- if AMQP.closing?
63
- # Do nothing, we're going down
64
- else
65
- launchitem = decode_launchitem( message )
66
- engine.launch( *launchitem )
67
- end
68
- end
69
- end
70
-
71
- def stop
72
- RuoteAMQP.stop!
73
- end
74
-
75
- private
76
-
77
- # Complicated guesswork that needs to happen here to detect the format
78
- def decode_launchitem( msg )
79
- hash = Rufus::Json.decode( msg )
80
- opts = {}
81
- definition = hash.delete('definition')
82
- fields = hash.delete('fields') || {}
83
- variables = hash.delete('variables') || {}
13
+ # @param [ Ruote::Engine, Ruote::Storage ] A configured ruote engine or storage instance
14
+ # @param opts :queue / :unsubscribe
15
+ #
16
+ def initialize(engine_or_storage, opts={})
84
17
 
85
- [ definition, fields, variables ]
18
+ super(engine_or_storage, opts.merge(:launchitems => :only))
86
19
  end
87
20
  end
88
21
  end
22
+
@@ -1,19 +1,37 @@
1
+
1
2
  require 'ruote/part/local_participant'
3
+ require 'ruote-amqp'
4
+
2
5
 
3
6
  module RuoteAMQP
4
7
 
8
+ #
5
9
  # = AMQP Participants
6
10
  #
7
- # The RuoteAMQP::Participant allows you to send workitems (serialized as
11
+ # The RuoteAMQP::ParticipantProxy allows you to send workitems (serialized as
8
12
  # JSON) or messages to any AMQP queues right from the process
9
- # definition. When combined with the RuoteAMQP::Listener you can easily
13
+ # definition. When combined with the RuoteAMQP::Receiver you can easily
10
14
  # leverage an extremely powerful local/remote participant
11
15
  # combinations.
12
16
  #
13
- # By default the participant relies on the presence of an AMQP
14
- # listener. Workitems are sent and no replies are given to the
15
- # engine. The participant can be configured to reply to the engine
16
- # immediately after queueing a message, see the usage section below.
17
+ # For local/remote participants The local part of the
18
+ # RuoteAMQP::ParticipantProxy relies on the presence of a
19
+ # RuoteAMQP::Receiver. Workitems are sent to the remote participant
20
+ # and the local part does not normally reply to the engine. Instead
21
+ # the engine will continue when a reply is received on the
22
+ # 'ruote_workitems' queue (see RuoteAMQP::Receiver).
23
+ #
24
+ # Of course, the standard :forget => true format can be used even
25
+ # with remote particpants and :forget can even be set as a default in
26
+ # the options.
27
+ #
28
+ # A simple way to create a remote participant to act upon workitems
29
+ # is to use the daemon-kit ruote responder.
30
+ #
31
+ # Simple AMQP messages are treated as 'fire and forget' and the flow
32
+ # will continue when the local participant has queued the message
33
+ # for sending. (As there is no meaningful way to receive a workitem
34
+ # in reply).
17
35
  #
18
36
  # == Configuration
19
37
  #
@@ -21,86 +39,59 @@ module RuoteAMQP
21
39
  # values of the +AMQP.settings+ hash, as provided by the AMQP
22
40
  # gem. No AMQP defaults are set by the participant.
23
41
  #
24
- # The participant requires version 0.6.1 or later of the amqp gem.
25
- #
26
42
  # == Usage
27
43
  #
28
- # Currently it's possible to send either workitems or messages
29
- # directly to a specific queue, and have the engine wait for
30
- # replies on another queue (see AMQPListener).
31
- #
32
- # Setting up the participant
44
+ # Define the queue used by an AMQP participant :
33
45
  #
34
46
  # engine.register_participant(
35
- # :amqp, RuoteAMQP::Participant )
47
+ # :delete_user, RuoteAMQP::ParticipantProxy, 'queue' => 'user_manager')
36
48
  #
37
- # Setup a participant that always replies to the engine
49
+ # Sending a workitem to the remote participant defined above:
38
50
  #
39
- # engine.register_participant(
40
- # :amqp, RuoteAMQP::Participant.new(:reply_by_default => true ) )
41
- #
42
- # Sending a message example
43
- #
44
- # class AmqpMessageExample0 < OpenWFE::ProcessDefinition
51
+ # Ruote.process_definition do
45
52
  # sequence do
46
- # amqp :queue => 'test', :message => 'foo'
53
+ # delete_user
47
54
  # end
48
55
  # end
49
56
  #
50
- # Sending a workitem
57
+ # Let the local participant reply to the engine without involving
58
+ # the receiver
51
59
  #
52
- # class AmqpWorkitemExample0 < OpenWFE::ProcessDefinition
60
+ # Ruote.process_definition do
53
61
  # sequence do
54
- # amqp :queue => 'test'
62
+ # delete_user :forget => true
55
63
  # end
56
64
  # end
57
65
  #
58
- # Let the participant reply to the engine without involving the listener
66
+ # Setting up the participant in a slightly more 'raw' way:
67
+ #
68
+ # engine.register_participant(
69
+ # :amqp, RuoteAMQP::ParticipantProxy )
70
+ #
71
+ # Sending a workitem to a specific queue:
59
72
  #
60
- # class AmqpWaitExample < OpenWFE::ProcessDefinition
73
+ # Ruote.process_definition do
61
74
  # sequence do
62
- # amqp :queue => 'test', :reply_anyway => true
75
+ # amqp :queue => 'test', 'command' => '/run/regression_test'
63
76
  # end
64
77
  # end
65
78
  #
66
- # When waiting for a reply it only makes sense to send a workitem.
67
- #
68
- # Keeping things DRY with participant name to queue maps:
69
- #
70
- # amqp = RuoteAMQP::Participant.new( :default_queue => 'test' )
71
- # amqp.map_participant 'george', 'whitehouse'
72
- # amqp.map_participant 'barak', 'whitehouse'
73
- # amqp.map_participant 'greenspan', 'treasury'
79
+ # Setup a 'fire and forget' participant that always replies to the
80
+ # engine:
74
81
  #
75
- # engine.register_participant( :george, amqp )
76
- # engine.register_participant( :barak, amqp )
77
- # engine.register_participant( :greespan, amqp )
78
- # engine.register_participant( :amqp, amqp )
79
- #
80
- # class DryAmqProcess0 < OpenWFE::ProcessDefinition
81
- # cursor :break_if => "${f:economy_recovered}" do
82
- # # Workitem sent to 'whitehouse' queue
83
- # george :activity => 'Tank economy'
84
- #
85
- # # Workitem sent to 'treasury' queue
86
- # greenspan :activity => 'Resign'
82
+ # engine.register_participant(
83
+ # :jfdi, RuoteAMQP::ParticipantProxy, 'forget' => true )
87
84
  #
88
- # # Workitem sent to 'whitehouse' queue
89
- # barak :activity => 'Cleanup mess'
85
+ # Sending a message example to a specific queue (both steps are
86
+ # equivalent):
90
87
  #
91
- # # Workitem sent to default 'test' queue
92
- # amqp :activity => 'Notify CNN'
88
+ # Ruote.process_definition do
89
+ # sequence do
90
+ # amqp :queue => 'test', :message => 'foo'
91
+ # amqp :queue => 'test', :message => 'foo', :forget => true
93
92
  # end
94
93
  # end
95
94
  #
96
- # == Workitem modifications
97
- #
98
- # To ease replies, and additional workitem attribute is set:
99
- #
100
- # 'reply_queue'
101
- #
102
- # +reply_queue+ has the name of the queue where the RuoteAMQP::Listener
103
- # expects replies from remote participants
104
95
  #
105
96
  # == AMQP notes
106
97
  #
@@ -112,27 +103,33 @@ module RuoteAMQP
112
103
  # participant, and messages are marked as persistent by default (see
113
104
  # #RuoteAMQP)
114
105
  #
115
- class Participant
106
+ class ParticipantProxy
116
107
 
117
108
  include Ruote::LocalParticipant
118
109
 
119
- # Accepts an options hash with the following keys:
110
+ # The following parameters are used in the process definition.
120
111
  #
121
- # * :reply_by_default => (bool) false by default
122
- # * :default_queue => (string) nil by default
123
- def initialize( options = {} )
112
+ # An options hash with the same keys to provide defaults is
113
+ # accepted at registration time (see above).
114
+ #
115
+ # * :queue => (string) The AMQP queue used by the remote participant.
116
+ # nil by default.
117
+ # * :forget => (bool) Whether the flow should block until the remote
118
+ # participant replies.
119
+ # false by default
120
+ #
121
+ def initialize(options)
122
+
124
123
  RuoteAMQP.start!
125
124
 
126
125
  @options = {
127
- :reply_by_default => false,
128
- :default_queue => nil
129
- }.merge( options )
130
-
131
- @participant_maps = {}
132
- end
133
-
134
- def map_participant( name, queue )
135
- @participant_maps[ name ] = queue
126
+ 'queue' => nil,
127
+ 'forget' => false,
128
+ }.merge(options.inject({}) { |h, (k, v)|
129
+ h[k.to_s] = v; h
130
+ })
131
+ #
132
+ # the inject is here to make sure that all options have String keys
136
133
  end
137
134
 
138
135
  # Process the workitem at hand. By default the workitem will be
@@ -140,47 +137,105 @@ module RuoteAMQP
140
137
  # workitem parameter. You can specify a +message+ workitem
141
138
  # parameter to have that sent instead of the workitem.
142
139
  #
143
- # To force the participant to reply to the engine, set the
144
- # +reply_anyway+ workitem parameter.
145
- def consume( workitem )
146
- if target_queue = determine_queue( workitem )
147
-
148
- q = MQ.queue( target_queue, :durable => true )
149
-
150
- # Message or workitem?
151
- if message = ( workitem.fields['message'] || workitem.fields['params']['message'] )
152
- q.publish( message, :persistent => RuoteAMQP.use_persistent_messages? )
153
- else
154
- q.publish( encode_workitem( workitem ), :persistent => RuoteAMQP.use_persistent_messages? )
155
- end
140
+ def consume(workitem)
141
+
142
+ target_queue = determine_queue(workitem)
143
+
144
+ raise 'no queue specified (outbound delivery)' unless target_queue
145
+
146
+ q = MQ.queue(target_queue, :durable => true)
147
+ forget = determine_forget(workitem)
148
+
149
+ opts = {
150
+ :persistent => RuoteAMQP.use_persistent_messages?,
151
+ :content_type => 'application/json' }
152
+
153
+ if message = workitem.fields['message'] || workitem.params['message']
154
+
155
+ forget = true # sending a message implies 'forget' => true
156
+
157
+ q.publish(message, opts)
158
+
156
159
  else
157
- raise "no queue in workitem params!"
158
- end
159
160
 
160
- if @options[:reply_by_default] || workitem.fields['params']['reply_anyway'] == true
161
- reply_to_engine( workitem )
161
+ q.publish(encode_workitem(workitem), opts)
162
162
  end
163
+
164
+ reply_to_engine(workitem) if forget
163
165
  end
164
166
 
167
+ # (Stops the underlying queue subscription)
168
+ #
165
169
  def stop
170
+
166
171
  RuoteAMQP.stop!
167
172
  end
168
173
 
169
174
  def cancel(fei, flavour)
175
+ #
176
+ # TODO : sending a cancel item is not a bad idea, especially if the
177
+ # job done over the amqp fence lasts...
178
+ #
179
+ end
180
+
181
+ # The current AMQP (0.6.7) has 1 queue per thread. If you let the default
182
+ # "one thread per participant consume call" kick in, you'll end up with
183
+ # 1 queue per consume call (and...)
184
+ #
185
+ # So, by returning true here, we force the queue to be always the same.
186
+ #
187
+ # Many thanks to https://github.com/weifeng365 for reporting this issue
188
+ # and suggesting the fix.
189
+ #
190
+ # TODO : should we have something to close queues when the engine / worker
191
+ # shuts down ?
192
+ # or is it already covered in the #stop ?
193
+ #
194
+ def do_not_thread
195
+
196
+ true
170
197
  end
171
198
 
172
199
  private
173
200
 
174
- def determine_queue( workitem )
175
- workitem.fields['params']['queue'] ||
176
- @participant_maps[ workitem.participant_name ] ||
177
- @options[:default_queue]
201
+ def determine_forget(workitem)
202
+
203
+ return workitem.params['forget'] if workitem.params.has_key?('forget')
204
+ return @options['forget'] if @options.has_key?('forget')
205
+ false
206
+ end
207
+
208
+ def determine_queue(workitem)
209
+
210
+ workitem.params['queue'] || @options['queue']
211
+ end
212
+
213
+ # Encodes the workitem as JSON. Makes sure to add to the field 'params'
214
+ # an entry named 'participant_options' which contains the options of
215
+ # this participant.
216
+ #
217
+ def encode_workitem(wi)
218
+
219
+ wi.params['participant_options'] = @options
220
+
221
+ Rufus::Json.encode(wi.to_h)
178
222
  end
223
+ end
224
+
225
+ #
226
+ # Kept for backward compatibility.
227
+ #
228
+ # You should use RuoteAMQP::ParticipantProxy.
229
+ #
230
+ class Participant < ParticipantProxy
179
231
 
180
- # Encode (and extend) the workitem as JSON
181
- def encode_workitem( wi )
182
- wi.fields['params']['reply_queue'] = WorkitemListener.queue
183
- wi.to_h.to_json
232
+ def initialize(options)
233
+ puts '=' * 80
234
+ puts "RuoteAMQP::Participant will be deprecated soon (2.1.12)"
235
+ puts "please use RuoteAMQP::ParticipantProxy instead"
236
+ puts '=' * 80
237
+ super
184
238
  end
185
239
  end
186
240
  end
241
+