smith 0.8.3 → 0.8.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|