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.
@@ -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
+