smith 0.6.7 → 0.6.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/agency +8 -7
- data/bin/smithctl +8 -0
- data/lib/smith.rb +1 -0
- data/lib/smith/agent.rb +22 -39
- data/lib/smith/bootstrap.rb +3 -1
- data/lib/smith/commands/agency/list.rb +12 -0
- data/lib/smith/self_pipe.rb +55 -0
- data/lib/smith/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 611c4332fcd1fcb21d1cb27a7792a4d2fb995454
|
4
|
+
data.tar.gz: f011eccef4892c74c23f1b37d717a5b3ad1f02e6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bb5a684361c835dadcd48020ec179739196535db0574c53c9cbd1268234947a356dcfa90788d8cb68288b3dd090e7028ff8b008d2017497f68fa913c18fca207
|
7
|
+
data.tar.gz: 1a0503cf8910994d9ae66865857aedf74b54e54aec1e390ba5c6c315084b8bfdf19e91d2694fa94a74cfe1bca53c3550a6ab82f9bab23fa7c01048fb3a84f3f4
|
data/bin/agency
CHANGED
@@ -32,13 +32,6 @@ module Smith
|
|
32
32
|
logger.info { "Shutting down" }
|
33
33
|
end
|
34
34
|
|
35
|
-
# Setup signal handlers to clean up.
|
36
|
-
%w{TERM INT QUIT}.each do |sig|
|
37
|
-
trap sig, proc {
|
38
|
-
logger.info { "Shutting down" }
|
39
|
-
@agency.stop
|
40
|
-
}
|
41
|
-
end
|
42
35
|
end
|
43
36
|
|
44
37
|
def run
|
@@ -49,6 +42,14 @@ module Smith
|
|
49
42
|
|
50
43
|
Smith.compile_acls
|
51
44
|
Smith.start do
|
45
|
+
|
46
|
+
signal_handler = SelfPipe.new(self)
|
47
|
+
# Setup signal handlers to clean up.
|
48
|
+
|
49
|
+
%w{TERM INT QUIT}.each do |sig|
|
50
|
+
signal_handler.install_signal_handler(sig) { @agency.stop }
|
51
|
+
end
|
52
|
+
|
52
53
|
# This block is here so the that the shutdown hook added in
|
53
54
|
# Smith.start runs last. Yes I know this is leaky but that's how
|
54
55
|
# it is at the moment.
|
data/bin/smithctl
CHANGED
@@ -94,6 +94,14 @@ Usage:
|
|
94
94
|
control = SmithControl.new(opts)
|
95
95
|
|
96
96
|
Smith.start do
|
97
|
+
|
98
|
+
signal_handler = SelfPipe.new(self)
|
99
|
+
# Setup signal handlers to clean up.
|
100
|
+
|
101
|
+
%w{TERM INT QUIT}.each do |sig|
|
102
|
+
signal_handler.install_signal_handler(sig) { @agency.stop }
|
103
|
+
end
|
104
|
+
|
97
105
|
control.send_command(command, args) do |result|
|
98
106
|
puts result if result && !result.empty?
|
99
107
|
Smith.stop(true)
|
data/lib/smith.rb
CHANGED
data/lib/smith/agent.rb
CHANGED
@@ -15,7 +15,8 @@ module Smith
|
|
15
15
|
|
16
16
|
@factory = QueueFactory.new
|
17
17
|
|
18
|
-
|
18
|
+
@signal_handler = SelfPipe.new(self)
|
19
|
+
|
19
20
|
setup_control_queue
|
20
21
|
|
21
22
|
@start_time = Time.now
|
@@ -25,6 +26,7 @@ module Smith
|
|
25
26
|
@on_stopping = proc {|completion| completion.succeed }
|
26
27
|
@on_starting = proc {|completion| completion.succeed }
|
27
28
|
@on_running = proc {|completion| completion.succeed }
|
29
|
+
@on_exception = proc {}
|
28
30
|
|
29
31
|
@on_starting_completion = EM::Completion.new.tap do |c|
|
30
32
|
c.completion do |completion|
|
@@ -67,50 +69,27 @@ module Smith
|
|
67
69
|
@on_running = blk
|
68
70
|
end
|
69
71
|
|
72
|
+
# The agent may hook into this if they want to do something on exception.
|
73
|
+
# It should be noted that, since an exception occured, the reactor will not
|
74
|
+
# be running at this point. Even if we restarted the reactor before calling
|
75
|
+
# this it would be a different reactor than existed when assigning the
|
76
|
+
# block so this would potentially lead to confusion. If the agent really
|
77
|
+
# needs the reactor to do something it can always restart the reactor
|
78
|
+
# itself.
|
79
|
+
#
|
80
|
+
# @param blk [Block] This block will be passed the exception as an
|
81
|
+
# argument.
|
82
|
+
def on_exception(&blk)
|
83
|
+
@on_exception = blk
|
84
|
+
end
|
85
|
+
|
70
86
|
# Override this method to implement your own agent.
|
71
87
|
def run
|
72
88
|
raise ArgumentError, "You must override this method"
|
73
89
|
end
|
74
90
|
|
75
|
-
# Set up the mechanics required to implement the self pipe trick.
|
76
|
-
def setup_signal_handlers
|
77
|
-
@signal_handlers = Hash.new { |h,k| h[k] = Array.new }
|
78
|
-
@signal_handler_queue = []
|
79
|
-
@signal_handler_pipe_reader, @signal_handler_pipe_writer = IO.pipe
|
80
|
-
|
81
|
-
# The Module declaration here will only close over local variables so we
|
82
|
-
# need to assign self to a local variable to get access to the agent itself.
|
83
|
-
agent = self
|
84
|
-
|
85
|
-
EM.attach(@signal_handler_pipe_reader, Module.new {
|
86
|
-
define_method :receive_data do |_|
|
87
|
-
|
88
|
-
handlers = agent.instance_variable_get(:@signal_handlers)
|
89
|
-
queue = agent.instance_variable_get(:@signal_handler_queue)
|
90
|
-
signal = queue.pop
|
91
|
-
|
92
|
-
# agent.send(:logger).debug { "Running signal handlers for agent: #{agent.name}: #{signal}" }
|
93
|
-
handlers[signal].each { |handler| handler.call(signal) }
|
94
|
-
end
|
95
|
-
})
|
96
|
-
end
|
97
|
-
|
98
|
-
# Adds a signal handler proc to the list of signal_handlers. When
|
99
|
-
# a signal is received all signal handlers are called in reverse order.
|
100
|
-
# @param signal [Integer] the signal number.
|
101
|
-
# @param position [Symbol] [:first|:last] where on the signal handler stack
|
102
|
-
# to put the handler proc.
|
103
|
-
# @see Signal.list for a full list of available signals on a system.
|
104
91
|
def install_signal_handler(signal, position=:end, &blk)
|
105
|
-
|
106
|
-
logger.debug { "Installing signal handler for #{signal}" }
|
107
|
-
|
108
|
-
@signal_handlers[signal].insert((position == :beginning) ? 0 : -1, blk)
|
109
|
-
|
110
|
-
Signal.trap(signal) {
|
111
|
-
@signal_handler_pipe_writer.write_nonblock('.')
|
112
|
-
@signal_handler_queue << signal
|
113
|
-
}
|
92
|
+
@signal_handler.install_signal_handler(signal, position=:end, &blk)
|
114
93
|
end
|
115
94
|
|
116
95
|
def state
|
@@ -239,5 +218,9 @@ module Smith
|
|
239
218
|
def control_queue_def
|
240
219
|
@control_queue_def ||= QueueDefinitions::Agent_control.call(uuid)
|
241
220
|
end
|
221
|
+
|
222
|
+
def __exception_handler(exception)
|
223
|
+
@on_exception.call(exception)
|
224
|
+
end
|
242
225
|
end
|
243
226
|
end
|
data/lib/smith/bootstrap.rb
CHANGED
@@ -65,7 +65,9 @@ module Smith
|
|
65
65
|
# be running. So it must be restarted and then shutdown again
|
66
66
|
# See the note at the in main.
|
67
67
|
def terminate!(exception=nil)
|
68
|
-
|
68
|
+
|
69
|
+
@agent.__send__(:__exception_handler, exception)
|
70
|
+
logger.error { format_exception(exception) }
|
69
71
|
logger.error { "Terminating: #{@agent_uuid}." }
|
70
72
|
|
71
73
|
if Smith.running?
|
@@ -1,7 +1,13 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require_relative '../common'
|
4
|
+
|
2
5
|
module Smith
|
3
6
|
module Commands
|
4
7
|
class List < CommandBase
|
8
|
+
|
9
|
+
include Common
|
10
|
+
|
5
11
|
def execute
|
6
12
|
if target.size > 0
|
7
13
|
selected_agents = agents.find_by_name(target)
|
@@ -9,6 +15,11 @@ module Smith
|
|
9
15
|
selected_agents = (options[:all]) ? agents.to_a : agents.state(:running)
|
10
16
|
end
|
11
17
|
|
18
|
+
if options[:group]
|
19
|
+
group_names = agent_group(options[:group])
|
20
|
+
selected_agents = selected_agents.select { |a| group_names.include?(a.name) }
|
21
|
+
end
|
22
|
+
|
12
23
|
responder.succeed((selected_agents.empty?) ? '' : format(selected_agents, options[:long]))
|
13
24
|
end
|
14
25
|
|
@@ -51,6 +62,7 @@ module Smith
|
|
51
62
|
banner "List the running agents."
|
52
63
|
|
53
64
|
opt :long, "the number of times to send the message", :short => :l
|
65
|
+
opt :group, "list only agents in this group", :type => :string, :short => :g
|
54
66
|
opt :one_column, "the number of times to send the message", :short => :s
|
55
67
|
opt :all, "show all agents in all states", :short => :a
|
56
68
|
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Smith
|
2
|
+
class SelfPipe
|
3
|
+
|
4
|
+
include Smith::Logger
|
5
|
+
|
6
|
+
def initialize(agent)
|
7
|
+
@agent = agent
|
8
|
+
|
9
|
+
@signal_handlers = Hash.new { |h,k| h[k] = Array.new }
|
10
|
+
@signal_handler_queue = []
|
11
|
+
@signal_handler_pipe_reader, @signal_handler_pipe_writer = IO.pipe
|
12
|
+
|
13
|
+
setup_signal_handlers
|
14
|
+
end
|
15
|
+
|
16
|
+
# Adds a signal handler proc to the list of signal_handlers. When
|
17
|
+
# a signal is received all signal handlers are called in reverse order.
|
18
|
+
#
|
19
|
+
# @param signal [Integer] the signal number.
|
20
|
+
# @param position [Symbol] [:first|:last] where on the signal handler stack
|
21
|
+
# to put the handler proc.
|
22
|
+
#
|
23
|
+
# @see Signal.list for a full list of available signals on a system.
|
24
|
+
def install_signal_handler(signal, position=:end, &blk)
|
25
|
+
raise ArgumentError, "Unknown position: #{position}" if ![:beginning, :end].include?(position)
|
26
|
+
logger.debug { "Installing signal handler for #{signal}" }
|
27
|
+
|
28
|
+
@signal_handlers[signal].insert((position == :beginning) ? 0 : -1, blk)
|
29
|
+
|
30
|
+
Signal.trap(signal) {
|
31
|
+
@signal_handler_pipe_writer.write_nonblock('.')
|
32
|
+
@signal_handler_queue << signal
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
# Set up the mechanics required to implement the self pipe trick.
|
37
|
+
def setup_signal_handlers
|
38
|
+
# The Module declaration here will only close over local variables so we
|
39
|
+
# need to assign self to a local variable to get access to the agent itself.
|
40
|
+
clazz = self
|
41
|
+
|
42
|
+
EM.attach(@signal_handler_pipe_reader, Module.new {
|
43
|
+
define_method :receive_data do |_|
|
44
|
+
|
45
|
+
handlers = clazz.instance_variable_get(:@signal_handlers)
|
46
|
+
queue = clazz.instance_variable_get(:@signal_handler_queue)
|
47
|
+
signal = queue.pop
|
48
|
+
|
49
|
+
clazz.send(:logger).debug { "Running signal handlers for: #{signal}" }
|
50
|
+
handlers[signal].each { |handler| handler.call(signal) }
|
51
|
+
end
|
52
|
+
})
|
53
|
+
end
|
54
|
+
end
|
55
|
+
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.6.
|
4
|
+
version: 0.6.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Richard Heycock
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: oj
|
@@ -254,6 +254,7 @@ files:
|
|
254
254
|
- lib/smith/messaging/util.rb
|
255
255
|
- lib/smith/object_count.rb
|
256
256
|
- lib/smith/queue_definitions.rb
|
257
|
+
- lib/smith/self_pipe.rb
|
257
258
|
- lib/smith/utils.rb
|
258
259
|
- lib/smith/version.rb
|
259
260
|
homepage: http://github.com/filterfish/smith2
|
@@ -276,9 +277,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
276
277
|
version: '0'
|
277
278
|
requirements: []
|
278
279
|
rubyforge_project: smith
|
279
|
-
rubygems_version: 2.
|
280
|
+
rubygems_version: 2.4.5
|
280
281
|
signing_key:
|
281
282
|
specification_version: 4
|
282
283
|
summary: Multi-agent framework
|
283
284
|
test_files: []
|
284
|
-
has_rdoc: false
|