smith 0.8.3 → 0.8.4
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.
- checksums.yaml +4 -4
- data/lib/smith/agent.rb +2 -4
- data/lib/smith/agent_process.rb +6 -4
- data/lib/smith/application/agency.rb +1 -1
- data/lib/smith/bootstrap.rb +13 -21
- data/lib/smith/logger.rb +1 -1
- data/lib/smith/messaging/receiver.rb +63 -5
- data/lib/smith/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5b0a3ce48b208c5e828b780e7cc46b9acaf52db8
|
|
4
|
+
data.tar.gz: 3ef6cffd4dbe62b2b385744ed02f85a667f22ada
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e154e8e5f9a581e8f68bb663cd9509daa56c7e1d0d7844c536c2566e3bdb19d0123e83dae47741107813e473a41f4f31173023ed06655d3724ffb730ab640b7d
|
|
7
|
+
data.tar.gz: 1960ac4441479753ac6e7bce7da67533d04497c292a7dac43e2041deb8f2e9383fcfd74be9a5a7d83b6884cf826cfdd2c77ccd0ce21798e0267960c3d8c4388f
|
data/lib/smith/agent.rb
CHANGED
|
@@ -32,7 +32,7 @@ module Smith
|
|
|
32
32
|
c.completion do |completion|
|
|
33
33
|
acknowledge_start do
|
|
34
34
|
@on_running.call(@on_running_completion)
|
|
35
|
-
logger.info { "Agent started: #{name}:
|
|
35
|
+
logger.info { "Agent started: #{name}, UUID: #{uuid}, PID: #{pid}" }
|
|
36
36
|
end
|
|
37
37
|
end
|
|
38
38
|
end
|
|
@@ -49,9 +49,7 @@ module Smith
|
|
|
49
49
|
c.completion do |completion|
|
|
50
50
|
acknowledge_stop do
|
|
51
51
|
@state = :stopping
|
|
52
|
-
Smith.stop
|
|
53
|
-
logger.info { "Agent stopped: #{name}:[#{pid}]." }
|
|
54
|
-
end
|
|
52
|
+
Smith.stop
|
|
55
53
|
end
|
|
56
54
|
end
|
|
57
55
|
end
|
data/lib/smith/agent_process.rb
CHANGED
|
@@ -199,8 +199,9 @@ module Smith
|
|
|
199
199
|
Process.detach(agent_process.pid)
|
|
200
200
|
end
|
|
201
201
|
|
|
202
|
+
# FIXME: This doesn't appear to be being called.
|
|
202
203
|
def self.acknowledge_start(agent_process, &blk)
|
|
203
|
-
logger.info { "Agent started: #{agent_process.uuid}" }
|
|
204
|
+
logger.info { "Agent started: #{agent_process.name}, UUID: #{agent_process.uuid}, PID: #{agent_process.pid}" }
|
|
204
205
|
end
|
|
205
206
|
|
|
206
207
|
def self.stop(agent_process)
|
|
@@ -209,7 +210,7 @@ module Smith
|
|
|
209
210
|
if count > 0
|
|
210
211
|
sender.publish(ACL::AgentCommand.new(:command => 'stop'))
|
|
211
212
|
else
|
|
212
|
-
logger.warn { "Agent is not listening. Setting state to dead." }
|
|
213
|
+
logger.warn { "Agent is not listening. Setting state to dead: #{agent_process.name}, UUID: #{agent_process.uuid}, PID: #{agent_process.pid}" }
|
|
213
214
|
agent_process.no_process_running
|
|
214
215
|
end
|
|
215
216
|
end
|
|
@@ -223,7 +224,7 @@ module Smith
|
|
|
223
224
|
|
|
224
225
|
def self.acknowledge_stop(agent_process)
|
|
225
226
|
agent_process.delete
|
|
226
|
-
logger.info { "Agent stopped: #{agent_process.uuid}" }
|
|
227
|
+
logger.info { "Agent stopped: #{agent_process.name}, UUID: #{agent_process.uuid}, PID: #{agent_process.pid}" }
|
|
227
228
|
end
|
|
228
229
|
|
|
229
230
|
# This needs to use the PID class to verify if an agent is still running.
|
|
@@ -234,7 +235,8 @@ module Smith
|
|
|
234
235
|
logger.info { "Agent's pid is 0. The agent probably didn't start correctly. Cleaning up." }
|
|
235
236
|
agent_process.delete
|
|
236
237
|
else
|
|
237
|
-
logger.info { "Sending
|
|
238
|
+
logger.info { "Sending signal: TERM, #{agent_process.name}, UUID: #{agent_process.uuid}, PID: #{agent_process.pid}" }
|
|
239
|
+
|
|
238
240
|
begin
|
|
239
241
|
Process.kill('TERM', agent_process.pid)
|
|
240
242
|
rescue
|
|
@@ -95,7 +95,7 @@ module Smith
|
|
|
95
95
|
def dead(agent_data)
|
|
96
96
|
agent_exists?(agent_data.uuid) do |agent_process|
|
|
97
97
|
if agent_process.no_process_running
|
|
98
|
-
logger.fatal { "Agent is dead: #{
|
|
98
|
+
logger.fatal { "Agent is dead: #{agent_process.name}, UUID: #{agent_process.uuid}, PID: #{agent_process.pid}" }
|
|
99
99
|
end
|
|
100
100
|
end
|
|
101
101
|
end
|
data/lib/smith/bootstrap.rb
CHANGED
|
@@ -25,6 +25,9 @@ module Smith
|
|
|
25
25
|
# thrown in setup_control_queue, for example, it just kills
|
|
26
26
|
# the agent without it actually raising the exception.
|
|
27
27
|
Thread.abort_on_exception = true
|
|
28
|
+
|
|
29
|
+
EventMachine.error_handler { |e| terminate!(e) }
|
|
30
|
+
|
|
28
31
|
@agent_name = name
|
|
29
32
|
@agent_uuid = uuid
|
|
30
33
|
end
|
|
@@ -33,7 +36,8 @@ module Smith
|
|
|
33
36
|
logger.debug { "Installing default signal handlers" }
|
|
34
37
|
%w{TERM INT QUIT}.each do |sig|
|
|
35
38
|
@agent.install_signal_handler(sig) do |sig|
|
|
36
|
-
logger.error { "
|
|
39
|
+
logger.error { "Received signal #{sig}: #{agent.name}, UUID: #{agent.uuid}, PID: #{agent.pid}." }
|
|
40
|
+
|
|
37
41
|
terminate!
|
|
38
42
|
end
|
|
39
43
|
end
|
|
@@ -71,19 +75,16 @@ module Smith
|
|
|
71
75
|
|
|
72
76
|
if Smith.running?
|
|
73
77
|
send_dead_message
|
|
74
|
-
|
|
75
|
-
Smith.stop
|
|
78
|
+
shutdown
|
|
76
79
|
else
|
|
77
|
-
logger.debug { "Reconnecting to AMQP Broker." }
|
|
78
80
|
Smith.start do
|
|
79
81
|
send_dead_message
|
|
80
|
-
|
|
81
|
-
Smith.stop
|
|
82
|
+
shutdown
|
|
82
83
|
end
|
|
83
84
|
end
|
|
84
85
|
end
|
|
85
86
|
|
|
86
|
-
#
|
|
87
|
+
# Cleanly shutdown of the agent.
|
|
87
88
|
def shutdown
|
|
88
89
|
unlink_pid_file
|
|
89
90
|
Smith.stop if Smith.running?
|
|
@@ -128,7 +129,7 @@ module Smith
|
|
|
128
129
|
@agent.__send__(:__exception_handler, exception) if @agent
|
|
129
130
|
logger.error { format_exception(exception) }
|
|
130
131
|
end
|
|
131
|
-
logger.error { "Terminating: #{@agent_uuid}." }
|
|
132
|
+
logger.error { "Terminating: #{@agent_name}, UUID: #{@agent_uuid}, PID: #{@pid.pid}." }
|
|
132
133
|
end
|
|
133
134
|
|
|
134
135
|
# Add the ../lib to the load path. This assumes the directory
|
|
@@ -168,18 +169,9 @@ Smith.compile_acls
|
|
|
168
169
|
|
|
169
170
|
bootstrapper = Smith::AgentBootstrap.new(name, uuid)
|
|
170
171
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
begin
|
|
176
|
-
Smith.start do
|
|
177
|
-
if bootstrapper.load_agent
|
|
178
|
-
bootstrapper.signal_handlers
|
|
179
|
-
bootstrapper.start!
|
|
180
|
-
end
|
|
172
|
+
Smith.start do
|
|
173
|
+
if bootstrapper.load_agent
|
|
174
|
+
bootstrapper.signal_handlers
|
|
175
|
+
bootstrapper.start!
|
|
181
176
|
end
|
|
182
|
-
bootstrapper.shutdown
|
|
183
|
-
rescue Exception => e
|
|
184
|
-
bootstrapper.terminate!(e)
|
|
185
177
|
end
|
data/lib/smith/logger.rb
CHANGED
|
@@ -18,6 +18,7 @@ module Smith
|
|
|
18
18
|
@acl_type_cache = AclTypeCache.instance
|
|
19
19
|
|
|
20
20
|
@foo_options = {
|
|
21
|
+
:error_queue => opts.delete(:error_queue) { false },
|
|
21
22
|
:auto_ack => option_or_default(@queue_def.options, :auto_ack, true),
|
|
22
23
|
:threading => option_or_default(@queue_def.options, :threading, false)}
|
|
23
24
|
|
|
@@ -95,7 +96,7 @@ module Smith
|
|
|
95
96
|
if !queue.subscribed?
|
|
96
97
|
opts = @options.subscribe
|
|
97
98
|
logger.debug { "Subscribing to: [queue]:#{@queue_def.denormalise} [options]:#{opts}" }
|
|
98
|
-
queue.subscribe(opts) do |metadata,payload|
|
|
99
|
+
queue.subscribe(opts) do |metadata, payload|
|
|
99
100
|
if payload
|
|
100
101
|
on_message(metadata, payload, requeue_options, &blk)
|
|
101
102
|
else
|
|
@@ -234,14 +235,20 @@ module Smith
|
|
|
234
235
|
end
|
|
235
236
|
end
|
|
236
237
|
|
|
238
|
+
# This class gets passed into the receive block and is a representation of
|
|
239
|
+
# both the message and the message metadata. It also handles requeues and
|
|
240
|
+
# retries. In short it's very much a convenience class which is why I have
|
|
241
|
+
# no idea what to call it!
|
|
242
|
+
#
|
|
237
243
|
class Foo
|
|
238
244
|
include Smith::Logger
|
|
239
245
|
|
|
240
246
|
attr_accessor :metadata
|
|
241
247
|
|
|
242
248
|
def initialize(metadata, data, opts={}, requeue_opts, &blk)
|
|
249
|
+
@opts = opts
|
|
243
250
|
@metadata = metadata
|
|
244
|
-
@reply_queue = opts[:reply_queue]
|
|
251
|
+
@reply_queue = @opts[:reply_queue]
|
|
245
252
|
@requeue_opts = requeue_opts
|
|
246
253
|
|
|
247
254
|
@acl_type_cache = AclTypeCache.instance
|
|
@@ -253,14 +260,14 @@ module Smith
|
|
|
253
260
|
|
|
254
261
|
@message = clazz.new.parse_from_string(data)
|
|
255
262
|
|
|
256
|
-
if opts[:threading]
|
|
263
|
+
if @opts[:threading]
|
|
257
264
|
EM.defer do
|
|
258
265
|
blk.call(@message, self)
|
|
259
|
-
ack if opts[:auto_ack]
|
|
266
|
+
ack if @opts[:auto_ack]
|
|
260
267
|
end
|
|
261
268
|
else
|
|
262
269
|
blk.call(@message, self)
|
|
263
|
-
ack if opts[:auto_ack]
|
|
270
|
+
ack if @opts[:auto_ack]
|
|
264
271
|
end
|
|
265
272
|
end
|
|
266
273
|
|
|
@@ -289,6 +296,40 @@ module Smith
|
|
|
289
296
|
end
|
|
290
297
|
alias :call :ack
|
|
291
298
|
|
|
299
|
+
# Publish the ACL to the error queue set up for this queue. This method is only
|
|
300
|
+
# available if the :error_queue option is set to true. Note this is the
|
|
301
|
+
# receive queue name which in most cases is the same at the sender name
|
|
302
|
+
# but if you are using fanout queues it will be different.
|
|
303
|
+
#
|
|
304
|
+
# @param [ACL] acl Optional ACL. With any options this method will fail the entire
|
|
305
|
+
# ACL. This may not be what you want though. So this opton allows
|
|
306
|
+
# you to fail another ACL. WARNING: there is no type checking at
|
|
307
|
+
# the moment. If you publish an ACL that this agent can't process
|
|
308
|
+
# and republish that ACL at a future date the agent will blow up.
|
|
309
|
+
#
|
|
310
|
+
# @param [Hash] opts Options hash. This currently only supports on option:
|
|
311
|
+
# :ack. If you publish a different ACL from the one received you will have to
|
|
312
|
+
# ack that message yourself and make sure `:ack => nil`
|
|
313
|
+
#
|
|
314
|
+
# @yieldparam [Fixnum] The number of ACLs on the error queue.
|
|
315
|
+
#
|
|
316
|
+
def fail(acl=nil, opts={:ack => true}, &blk)
|
|
317
|
+
if @opts[:error_queue]
|
|
318
|
+
message = (acl) ? acl : @message
|
|
319
|
+
Sender.new("#{queue_name}.error") do |queue|
|
|
320
|
+
logger.debug { "Republishing ACL to error queue: \"#{queue.queue_name}\"" }
|
|
321
|
+
queue.publish(message) do
|
|
322
|
+
queue.number_of_messages do |count|
|
|
323
|
+
@metadata.ack if opts[:ack]
|
|
324
|
+
blk && blk && blk.call(count + 1)
|
|
325
|
+
end
|
|
326
|
+
end
|
|
327
|
+
end
|
|
328
|
+
else
|
|
329
|
+
raise ArgumentError, "You cannot fail this queue as you haven't specified the :error_queue option"
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
|
|
292
333
|
# Make #call invoke ack. This makes the following idiom possible:
|
|
293
334
|
#
|
|
294
335
|
# receiver('queue').subscribe do |payload, receiver|
|
|
@@ -309,6 +350,23 @@ module Smith
|
|
|
309
350
|
def correlation_id
|
|
310
351
|
@metadata.correlation_id
|
|
311
352
|
end
|
|
353
|
+
|
|
354
|
+
# Return the queue_name. Note this is the receive queue name which in
|
|
355
|
+
# most cases is the same at the sender name but if you are using fanout
|
|
356
|
+
# queues it will be different.
|
|
357
|
+
#
|
|
358
|
+
# @return [String] the name of the queue
|
|
359
|
+
#
|
|
360
|
+
def queue_name
|
|
361
|
+
begin
|
|
362
|
+
@a561facf ||= @metadata.channel.queues.detect { |queue| queue.bindings.first[:exchange] == @metadata.exchange }.name.gsub(/^#{Smith.config.smith.namespace}\./, '')
|
|
363
|
+
rescue NoMethodError
|
|
364
|
+
# If `bingings` is empty then an exception will be raised. I cannot
|
|
365
|
+
# see how it can possibly happend but if it does raise a slightly
|
|
366
|
+
# more informative exceptino
|
|
367
|
+
raise "Missing queue. This cannot happen and probably represents a bug. Exchange: #{@metadata.exchange}"
|
|
368
|
+
end
|
|
369
|
+
end
|
|
312
370
|
end
|
|
313
371
|
end
|
|
314
372
|
end
|
data/lib/smith/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: smith
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.8.
|
|
4
|
+
version: 0.8.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Richard Heycock
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2016-02-
|
|
11
|
+
date: 2016-02-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: amqp
|