isono 0.1.0 → 0.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.
- data/.gitignore +2 -0
- data/Rakefile +38 -0
- data/isono.gemspec +13 -12
- data/lib/isono.rb +5 -4
- data/lib/isono/amqp_client.rb +71 -42
- data/lib/isono/logger.rb +19 -9
- data/lib/isono/manifest.rb +9 -10
- data/lib/isono/node.rb +41 -25
- data/lib/isono/node_modules/base.rb +25 -9
- data/lib/isono/node_modules/event_channel.rb +18 -7
- data/lib/isono/node_modules/job_channel.rb +20 -21
- data/lib/isono/node_modules/job_worker.rb +47 -28
- data/lib/isono/node_modules/rpc_channel.rb +46 -96
- data/lib/isono/rack/job.rb +19 -32
- data/lib/isono/runner/base.rb +150 -0
- data/lib/isono/runner/cli.rb +28 -0
- data/lib/isono/runner/rpc_server.rb +21 -53
- data/lib/isono/thread_pool.rb +24 -19
- data/lib/isono/util.rb +12 -4
- data/lib/isono/version.rb +5 -0
- data/spec/amqp_client_spec.rb +71 -0
- data/spec/event_observable_spec.rb +6 -0
- data/spec/file_channel_spec.rb +263 -0
- data/spec/job_channel_spec.rb +47 -0
- data/spec/logger_spec.rb +45 -0
- data/spec/manifest_spec.rb +43 -0
- data/spec/node_spec.rb +64 -0
- data/spec/resource_loader_spec.rb +113 -0
- data/spec/rpc_channel_spec.rb +172 -0
- data/spec/spec_helper.rb +62 -0
- data/spec/thread_pool_spec.rb +35 -0
- data/spec/util_spec.rb +38 -0
- data/tasks/load_resource_manifest.rake +7 -0
- metadata +79 -43
- data/lib/isono/runner/agent.rb +0 -89
@@ -7,6 +7,7 @@ module Isono
|
|
7
7
|
attr_reader :node
|
8
8
|
|
9
9
|
def initialize(node)
|
10
|
+
raise ArgumentError unless node.is_a?(Node)
|
10
11
|
@node = node
|
11
12
|
|
12
13
|
raise "Module initializer_hook is not run yet" if self.value_object.nil?
|
@@ -18,10 +19,6 @@ module Isono
|
|
18
19
|
node.manifest
|
19
20
|
end
|
20
21
|
|
21
|
-
def amq
|
22
|
-
node.amq
|
23
|
-
end
|
24
|
-
|
25
22
|
def value_object
|
26
23
|
node.value_objects[self.class]
|
27
24
|
end
|
@@ -34,19 +31,37 @@ module Isono
|
|
34
31
|
|
35
32
|
module ClassMethods
|
36
33
|
def initialize_hook(&blk)
|
37
|
-
@
|
38
|
-
@initialize_hook
|
34
|
+
@node_hooks[:initialize] = blk
|
39
35
|
end
|
40
36
|
|
41
37
|
def terminate_hook(&blk)
|
42
|
-
@
|
43
|
-
|
38
|
+
@node_hooks[:terminate] = blk
|
39
|
+
end
|
40
|
+
|
41
|
+
def before_connect_hook(&blk)
|
42
|
+
@node_hooks[:before_connect] = blk
|
43
|
+
end
|
44
|
+
|
45
|
+
def after_connect_hook(&blk)
|
46
|
+
@node_hooks[:after_connect] = blk
|
47
|
+
end
|
48
|
+
|
49
|
+
def before_close_hook(&blk)
|
50
|
+
@node_hooks[:before_close] = blk
|
51
|
+
end
|
52
|
+
|
53
|
+
def after_close_hook(&blk)
|
54
|
+
@node_hooks[:after_close] = blk
|
44
55
|
end
|
45
56
|
|
46
57
|
def config_section(name=nil, &blk)
|
47
58
|
@config_section_name = name unless name.nil?
|
48
59
|
@config_section_builder = blk
|
49
|
-
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def node_hooks
|
63
|
+
@node_hooks
|
64
|
+
end
|
50
65
|
end
|
51
66
|
|
52
67
|
protected
|
@@ -57,6 +72,7 @@ module Isono
|
|
57
72
|
# set the default config section name from its class name.
|
58
73
|
# can be overwritten later.
|
59
74
|
@config_section_name = Util.snake_case(self.to_s.split('::').last)
|
75
|
+
@node_hooks = {}
|
60
76
|
}
|
61
77
|
end
|
62
78
|
|
@@ -20,7 +20,18 @@ module Isono
|
|
20
20
|
AMQP_EXCHANGE='isono.event'
|
21
21
|
|
22
22
|
initialize_hook do
|
23
|
-
amq.
|
23
|
+
@amq = node.create_channel
|
24
|
+
@amq.instance_eval {
|
25
|
+
def event_exchange
|
26
|
+
self.topic(AMQP_EXCHANGE, {:auto_delete=>false})
|
27
|
+
end
|
28
|
+
}
|
29
|
+
|
30
|
+
# create the exchange
|
31
|
+
@amq.event_exchange
|
32
|
+
end
|
33
|
+
|
34
|
+
terminate_hook do
|
24
35
|
end
|
25
36
|
|
26
37
|
# @example
|
@@ -37,14 +48,14 @@ module Isono
|
|
37
48
|
}
|
38
49
|
|
39
50
|
EventMachine.schedule {
|
40
|
-
amq.
|
41
|
-
|
42
|
-
|
51
|
+
@amq.event_exchange.publish(Serializer.instance.marshal(body),
|
52
|
+
{:key=>"#{evname}.#{opts[:sender]}"}
|
53
|
+
)
|
43
54
|
}
|
44
55
|
end
|
45
56
|
|
46
|
-
def subscribe(evname, sender, receiver_id=node.node_id, &blk)
|
47
|
-
amq.queue("#{evname}-#{receiver_id}", {:exclusive=>true}).bind(
|
57
|
+
def subscribe(evname, sender='#', receiver_id=node.node_id, &blk)
|
58
|
+
@amq.queue("#{evname}-#{receiver_id}", {:exclusive=>true}).bind(
|
48
59
|
AMQP_EXCHANGE, :key=>"#{evname}.#{sender}"
|
49
60
|
).subscribe { |data|
|
50
61
|
data = Serializer.instance.unmarshal(data)
|
@@ -62,7 +73,7 @@ module Isono
|
|
62
73
|
|
63
74
|
def unsubscribe(evname, receiver_id=node.node_id)
|
64
75
|
EventMachine.schedule {
|
65
|
-
q = amq.queue("#{evname}-#{receiver_id}")
|
76
|
+
q = @amq.queue("#{evname}-#{receiver_id}")
|
66
77
|
q.unsubscribe
|
67
78
|
}
|
68
79
|
end
|
@@ -4,7 +4,14 @@ module Isono
|
|
4
4
|
module NodeModules
|
5
5
|
class JobChannel < Base
|
6
6
|
|
7
|
-
|
7
|
+
config_section do |c|
|
8
|
+
desc "default timeout duration in second"
|
9
|
+
c.timeout_sec = (60*60*24).to_f
|
10
|
+
desc "default job concurrency"
|
11
|
+
c.concurrency = 1
|
12
|
+
end
|
13
|
+
|
14
|
+
# Send a new job request to the endpoint.
|
8
15
|
#
|
9
16
|
# @param [String] endpoint endpoint name created by JobChannel#register_endpoint()
|
10
17
|
# @param [String] command command name in the endpoint.
|
@@ -13,24 +20,14 @@ module Isono
|
|
13
20
|
# method will stop the current thread if it does not exist.
|
14
21
|
# @return [Rack::Request,String] Request object if the block is given.
|
15
22
|
#
|
16
|
-
# @example call job endpoint 'endpoint1'
|
17
|
-
#
|
23
|
+
# @example call job endpoint 'endpoint1'.
|
24
|
+
# puts submit('endpoint1', 'command1', 1, 2, 3) # => show Job ID
|
18
25
|
def submit(endpoint, command, *args, &blk)
|
19
|
-
|
20
|
-
|
21
|
-
req.request[:job_request_type]=:submit
|
22
|
-
|
23
|
-
# A job is working on this current thread if cur_job_ctx is
|
24
|
-
# not nil. Let the new job know the current job ID
|
25
|
-
# as its parent job ID.
|
26
|
-
if cur_job_ctx
|
27
|
-
req.request[:parent_job_id] = cur_job_ctx.job_id
|
28
|
-
end
|
29
|
-
|
30
|
-
blk ? blk.call(req) : req.synchronize
|
26
|
+
req = run(endpoint, command, *args) { |req|
|
27
|
+
blk.call(req) if blk
|
31
28
|
}
|
32
29
|
|
33
|
-
|
30
|
+
req.request[:job_id]
|
34
31
|
end
|
35
32
|
|
36
33
|
# Send a new job request and wait until the job finished.
|
@@ -54,8 +51,9 @@ module Isono
|
|
54
51
|
def run(endpoint, command, *args, &blk)
|
55
52
|
cur_job_ctx = Thread.current[JobWorker::JOB_CTX_KEY]
|
56
53
|
req = rpc.request("job.#{endpoint}", command, *args) { |req|
|
57
|
-
req.
|
58
|
-
|
54
|
+
req.timeout = config_section.timeout_sec
|
55
|
+
req.request[:job_id] = Util.gen_id
|
56
|
+
|
59
57
|
# A job is working on this current thread if cur_job_ctx is
|
60
58
|
# not nil. Let the new job know the current job ID
|
61
59
|
# as its parent job ID.
|
@@ -69,11 +67,12 @@ module Isono
|
|
69
67
|
blk ? req : req.wait
|
70
68
|
end
|
71
69
|
|
72
|
-
def cancel()
|
70
|
+
def cancel(job_id)
|
73
71
|
end
|
74
72
|
|
75
|
-
def register_endpoint(endpoint, app)
|
76
|
-
|
73
|
+
def register_endpoint(endpoint, app, opts={})
|
74
|
+
opts = {:concurrency=>config_section.concurrency}.merge(opts)
|
75
|
+
rpc.register_endpoint("job.#{endpoint}", Rack::Job.new(app, JobWorker.new(node)), {:prefetch=>opts[:concurrency]})
|
77
76
|
end
|
78
77
|
|
79
78
|
private
|
@@ -8,9 +8,13 @@ module Isono
|
|
8
8
|
include Logger
|
9
9
|
|
10
10
|
JOB_CTX_KEY=:job_worker_ctx
|
11
|
+
|
12
|
+
config_section do |c|
|
13
|
+
c.concurrency = 1
|
14
|
+
end
|
11
15
|
|
12
16
|
initialize_hook do
|
13
|
-
@thread_pool = ThreadPool.new(
|
17
|
+
@thread_pool = ThreadPool.new(config_section.concurrency.to_i)
|
14
18
|
@active_jobs = {}
|
15
19
|
|
16
20
|
RpcChannel.new(node).register_endpoint("job-stats.#{node.node_id}", proc { |req, res|
|
@@ -29,30 +33,17 @@ module Isono
|
|
29
33
|
|
30
34
|
# Start a new long term job.
|
31
35
|
#
|
32
|
-
# @
|
33
|
-
# @param [Proc,nil] run_cb
|
34
|
-
# @param [Proc,nil] fail_cb
|
35
|
-
# @yield The block used as run_cb
|
36
|
+
# @yield The block to setup JobContext object.
|
36
37
|
#
|
37
|
-
# @example
|
38
|
-
#
|
39
|
-
# #
|
38
|
+
# @example Initialize JobContext within the block.
|
39
|
+
# start { |ctx|
|
40
|
+
# # setup JobContext
|
41
|
+
# ctx.job_id = 'xxxx'
|
42
|
+
# ctx.parent_job_id = 'yyyy'
|
40
43
|
# }
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
# }, proc{
|
45
|
-
# # do rollback on fail
|
46
|
-
# })
|
47
|
-
def run(parent_id=nil, run_cb=nil, fail_cb=nil, &blk)
|
48
|
-
if run_cb.is_a?(Proc)
|
49
|
-
job = JobContext.new(run_cb, parent_id)
|
50
|
-
job.fail_cb = fail_cb if fail_cb.is_a?(Proc)
|
51
|
-
elsif blk
|
52
|
-
job = JobContext.new(blk, parent_id)
|
53
|
-
else
|
54
|
-
raise ArgumentError, "callbacks were not set propery"
|
55
|
-
end
|
44
|
+
def start(&blk)
|
45
|
+
job = JobContext.new()
|
46
|
+
blk.call(job)
|
56
47
|
@active_jobs[job.job_id] = job
|
57
48
|
rpc = RpcChannel.new(node)
|
58
49
|
|
@@ -87,19 +78,47 @@ module Isono
|
|
87
78
|
job
|
88
79
|
end
|
89
80
|
|
81
|
+
# Run the block/proc. This is simple utility method for start().
|
82
|
+
#
|
83
|
+
# @param [Proc,nil] run_cb
|
84
|
+
# @param [Proc,nil] fail_cb
|
85
|
+
#
|
86
|
+
# @example Run
|
87
|
+
# run {
|
88
|
+
# puts "message"
|
89
|
+
# }
|
90
|
+
# @example Use proc{} for setting both run and fail block.
|
91
|
+
# run(proc{
|
92
|
+
# # do something
|
93
|
+
# }, proc{
|
94
|
+
# # do rollback on fail
|
95
|
+
# })
|
96
|
+
def run(run_cb=nil, fail_cb=nil, &blk)
|
97
|
+
if run_cb.is_a?(Proc)
|
98
|
+
start do |job|
|
99
|
+
job.run_cb = run_cb
|
100
|
+
job.fail_cb = fail_cb if fail_cb.is_a?(Proc)
|
101
|
+
end
|
102
|
+
elsif blk
|
103
|
+
start do |job|
|
104
|
+
job.run_cb = blk
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
90
109
|
class JobContext < OpenStruct
|
91
110
|
include Logger
|
92
|
-
attr_reader :stm
|
93
|
-
attr_accessor :fail_cb
|
111
|
+
attr_reader :stm
|
112
|
+
attr_accessor :run_cb, :fail_cb
|
94
113
|
|
95
|
-
def initialize(
|
114
|
+
def initialize()
|
96
115
|
super({:job_id=>Util.gen_id,
|
97
|
-
:parent_job_id=>
|
116
|
+
:parent_job_id=>nil,
|
98
117
|
:started_at=>nil,
|
99
118
|
:finished_at=>nil,
|
100
119
|
})
|
101
120
|
|
102
|
-
@run_cb=
|
121
|
+
@run_cb=proc{}
|
103
122
|
@fail_cb=nil
|
104
123
|
|
105
124
|
@stm = Statemachine.build {
|
@@ -9,8 +9,6 @@ module Isono
|
|
9
9
|
class RpcChannel < Base
|
10
10
|
include Logger
|
11
11
|
|
12
|
-
AMQP_EXCHANGE='isono.rpc'
|
13
|
-
|
14
12
|
class RpcError < RuntimeError; end
|
15
13
|
class UnknownEndpointError < RpcError; end
|
16
14
|
class DuplicateEndpointError < RpcError; end
|
@@ -23,14 +21,12 @@ module Isono
|
|
23
21
|
initialize_hook do
|
24
22
|
@active_requests = {}
|
25
23
|
@endpoints = {}
|
26
|
-
amq.
|
27
|
-
amq.queue("command-recv.#{manifest.node_id}", {:exclusive=>true}).subscribe { |header, data|
|
28
|
-
event = EventChannel.new(self.node)
|
24
|
+
@amq = node.create_channel
|
25
|
+
@amq.queue("command-recv.#{manifest.node_id}", {:exclusive=>true}).subscribe { |header, data|
|
29
26
|
req = @active_requests[header.message_id]
|
30
27
|
if req
|
31
28
|
data = Serializer.instance.unmarshal(data)
|
32
29
|
req.process_event(:on_received, data)
|
33
|
-
event.publish('rpc/response_received', :args=>[header.message_id])
|
34
30
|
begin
|
35
31
|
case data[:type]
|
36
32
|
when :inprogress
|
@@ -69,9 +65,11 @@ module Isono
|
|
69
65
|
@endpoints.keys.each { |ns|
|
70
66
|
myinstance.unregister_endpoint(ns)
|
71
67
|
}
|
72
|
-
amq.queue("command-recv.#{manifest.node_id}", {:exclusive=>true}).delete
|
68
|
+
@amq.queue("command-recv.#{manifest.node_id}", {:exclusive=>true}).delete
|
73
69
|
end
|
74
70
|
|
71
|
+
attr_reader :amq
|
72
|
+
|
75
73
|
# Make a RPC request to an endpoint.
|
76
74
|
#
|
77
75
|
# @param [String] endpoint
|
@@ -112,24 +110,11 @@ module Isono
|
|
112
110
|
# async
|
113
111
|
r = blk.call(req)
|
114
112
|
req = r if r.is_a?(RequestContext)
|
115
|
-
|
116
|
-
send_request(req)
|
117
|
-
else
|
118
|
-
check_endpoint(endpoint) { |result|
|
119
|
-
if result
|
120
|
-
send_request(req)
|
121
|
-
else
|
122
|
-
e = UnknownEndpointError.new(endpoint)
|
123
|
-
req.error_cb.call(e) if req.error_cb
|
124
|
-
end
|
125
|
-
}
|
126
|
-
end
|
127
|
-
|
113
|
+
send_request(req)
|
128
114
|
req
|
129
115
|
else
|
130
116
|
# sync
|
131
117
|
req = req.synchronize
|
132
|
-
check_endpoint(endpoint) || raise(UnknownEndpointError, endpoint)
|
133
118
|
send_request(req)
|
134
119
|
req.wait
|
135
120
|
end
|
@@ -141,21 +126,21 @@ module Isono
|
|
141
126
|
# @param [String] endpoint
|
142
127
|
# @param [has call() method] app
|
143
128
|
# @param [Hash] opts
|
129
|
+
# :exclusive
|
130
|
+
# :prefetch
|
144
131
|
def register_endpoint(endpoint, app, opts={})
|
145
132
|
raise TypeError unless app.respond_to?(:call)
|
146
|
-
opts = {:exclusive=>true}.merge(opts)
|
147
|
-
@endpoints[endpoint]={:app=>app, :opts=>opts}
|
133
|
+
opts = {:exclusive=>true, :prefetch=>0}.merge(opts)
|
148
134
|
|
149
135
|
# create receive queue for new RPC endpoint.
|
150
136
|
endpoint_proc = proc { |header, data|
|
151
137
|
|
152
138
|
data = Serializer.instance.unmarshal(data)
|
153
|
-
event.publish('rpc/request_received', :args=>[header.message_id])
|
154
139
|
|
155
140
|
resctx = if data[:oneshot]
|
156
|
-
OneshotResponseContext.new(
|
141
|
+
OneshotResponseContext.new(@endpoints[endpoint][:ch].response_exchange, header)
|
157
142
|
else
|
158
|
-
ResponseContext.new(
|
143
|
+
ResponseContext.new(@endpoints[endpoint][:ch].response_exchange, header)
|
159
144
|
end
|
160
145
|
begin
|
161
146
|
req = Rack::Request.new({:sender=>header.reply_to['command-recv.'.size..-1],
|
@@ -163,81 +148,51 @@ module Isono
|
|
163
148
|
}.merge(data))
|
164
149
|
res = Rack::Response.new(resctx)
|
165
150
|
ret = app.call(req, res)
|
166
|
-
rescue Exception => e
|
151
|
+
rescue ::Exception => e
|
167
152
|
logger.error(e)
|
168
153
|
resctx.response(e) unless resctx.responded?
|
169
154
|
end
|
170
155
|
}
|
171
156
|
|
172
|
-
setup_proc = proc {
|
173
|
-
amq.queue(endpoint_queue_name(endpoint), {:exclusive=>false, :auto_delete=>true}).bind(
|
174
|
-
AMQP_EXCHANGE, {:key=>endpoint_queue_name(endpoint)}
|
175
|
-
).subscribe(:ack=>true, &endpoint_proc)
|
176
|
-
event.publish('rpc/register', :args=>[endpoint])
|
177
|
-
}
|
178
|
-
|
179
|
-
dm = Util::DeferedMsg.new(30)
|
180
157
|
|
181
158
|
EventMachine.schedule {
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
dm.success
|
159
|
+
ch = if opts[:prefetch].to_i > 0
|
160
|
+
# create per endpoint channel
|
161
|
+
node.create_channel
|
162
|
+
else
|
163
|
+
# use default channel
|
164
|
+
@amq
|
165
|
+
end
|
166
|
+
ch.instance_eval %Q{
|
167
|
+
def endpoint_queue
|
168
|
+
self.queue("isono.rpc.endpoint.#{endpoint}", {:exclusive=>false, :auto_delete=>true})
|
193
169
|
end
|
194
170
|
|
195
|
-
|
196
|
-
|
197
|
-
|
171
|
+
def response_exchange
|
172
|
+
self.direct('')
|
173
|
+
end
|
198
174
|
}
|
199
|
-
|
175
|
+
ch.prefetch(opts[:prefetch].to_i) if opts[:prefetch].to_i > 0
|
176
|
+
# stores hash here that is for thread safety.
|
177
|
+
@endpoints[endpoint]={:app=>app, :opts=>opts, :ch=>ch}
|
200
178
|
|
201
|
-
|
179
|
+
ch.endpoint_queue.subscribe(:ack=>true, &endpoint_proc)
|
180
|
+
event.publish('rpc/register', :args=>[endpoint])
|
181
|
+
}
|
202
182
|
end
|
203
183
|
|
204
184
|
# Unregister endpoint.
|
205
185
|
#
|
206
186
|
# @param [String] endpoint endpoint name to be removed
|
207
187
|
def unregister_endpoint(endpoint)
|
208
|
-
if @endpoints.
|
209
|
-
dm = Util::DeferedMsg.new(30)
|
188
|
+
if @endpoints.has_key?(endpoint)
|
210
189
|
EventMachine.schedule {
|
211
|
-
|
190
|
+
data = @endpoints.delete(endpoint)
|
191
|
+
# endpoint_queue is :auto_delete=>true so that it will be deleted
|
192
|
+
# in case of zero consumers.
|
193
|
+
data[:ch].endpoint_queue.unsubscribe
|
212
194
|
event.publish('rpc/unregister', :args=>[endpoint])
|
213
|
-
dm.success
|
214
195
|
}
|
215
|
-
dm.wait unless EventMachine.reactor_thread?
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
|
-
# Check if the endpoint exists.
|
220
|
-
# @param [String] endpoint endpoint name to be checked
|
221
|
-
def check_endpoint(endpoint, &blk)
|
222
|
-
if blk
|
223
|
-
else
|
224
|
-
dm = Util::DeferedMsg.new(30)
|
225
|
-
end
|
226
|
-
|
227
|
-
EventMachine.schedule {
|
228
|
-
amq.queue(endpoint_queue_name(endpoint), {:exclusive=>false, :auto_delete=>true}).status { |messages, consumers|
|
229
|
-
res = consumers.to_i > 0
|
230
|
-
if blk
|
231
|
-
blk.call(res)
|
232
|
-
else
|
233
|
-
dm.success(res)
|
234
|
-
end
|
235
|
-
}
|
236
|
-
}
|
237
|
-
|
238
|
-
if blk
|
239
|
-
else
|
240
|
-
dm.wait unless EventMachine.reactor_thread?
|
241
196
|
end
|
242
197
|
end
|
243
198
|
|
@@ -280,24 +235,22 @@ module Isono
|
|
280
235
|
if !req.oneshot
|
281
236
|
@active_requests[req.ticket] = req
|
282
237
|
end
|
283
|
-
|
284
|
-
amq.direct(
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
)
|
238
|
+
|
239
|
+
amq.direct('').publish(Serializer.instance.marshal(req.request_hash),
|
240
|
+
{:message_id => req.ticket,
|
241
|
+
:key => endpoint_queue_name(req.endpoint),
|
242
|
+
:reply_to=>"command-recv.#{manifest.node_id}"}
|
243
|
+
)
|
290
244
|
req.process_event(:on_sent)
|
291
|
-
event.publish('rpc/request_sent', :args=>[req.hash])
|
292
245
|
}
|
293
246
|
end
|
294
247
|
|
295
248
|
class ResponseContext
|
296
|
-
attr_reader :
|
249
|
+
attr_reader :header
|
297
250
|
|
298
|
-
def initialize(
|
251
|
+
def initialize(exchange, header)
|
299
252
|
@responded = false
|
300
|
-
@
|
253
|
+
@exchange = exchange
|
301
254
|
@header = header
|
302
255
|
end
|
303
256
|
|
@@ -321,15 +274,13 @@ module Isono
|
|
321
274
|
else
|
322
275
|
publish(:success, ret)
|
323
276
|
end
|
324
|
-
EventChannel.new(@node).publish('rpc/response_sent', :args=>[@header.message_id])
|
325
277
|
}
|
326
278
|
@responded = true
|
327
279
|
end
|
328
280
|
|
329
|
-
|
330
281
|
private
|
331
282
|
def publish(type, body)
|
332
|
-
@
|
283
|
+
@exchange.publish(Serializer.instance.marshal({:type=>type, :msg=>body}),
|
333
284
|
{:key=>@header.reply_to,
|
334
285
|
:message_id=>@header.message_id}
|
335
286
|
)
|
@@ -347,7 +298,6 @@ module Isono
|
|
347
298
|
|
348
299
|
EM.schedule {
|
349
300
|
@header.ack
|
350
|
-
EventChannel.new(@node).publish('rpc/response_sent', :args=>[@header.message_id])
|
351
301
|
}
|
352
302
|
@responded = true
|
353
303
|
end
|