asir 1.1.12 → 1.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 +1 -0
- data/ChangeLog +8 -1
- data/example/ex18.rb +3 -2
- data/example/ex26.rb +1 -1
- data/example/example_helper.rb +12 -2
- data/lib/asir.rb +1 -0
- data/lib/asir/additional_data.rb +4 -4
- data/lib/asir/client.rb +1 -2
- data/lib/asir/identity.rb +2 -18
- data/lib/asir/message/state.rb +18 -0
- data/lib/asir/transport.rb +53 -45
- data/lib/asir/transport/broadcast.rb +4 -5
- data/lib/asir/transport/buffer.rb +4 -4
- data/lib/asir/transport/composite.rb +1 -1
- data/lib/asir/transport/conduit.rb +8 -6
- data/lib/asir/transport/connection_oriented.rb +15 -12
- data/lib/asir/transport/database.rb +9 -11
- data/lib/asir/transport/delegation.rb +7 -12
- data/lib/asir/transport/demux.rb +2 -2
- data/lib/asir/transport/fallback.rb +4 -4
- data/lib/asir/transport/file.rb +6 -8
- data/lib/asir/transport/http.rb +11 -6
- data/lib/asir/transport/local.rb +8 -6
- data/lib/asir/transport/null.rb +1 -1
- data/lib/asir/transport/payload_io.rb +2 -2
- data/lib/asir/transport/rack.rb +7 -9
- data/lib/asir/transport/retry.rb +6 -5
- data/lib/asir/transport/subprocess.rb +5 -4
- data/lib/asir/transport/tcp_socket.rb +5 -5
- data/lib/asir/transport/thread.rb +12 -6
- data/lib/asir/transport/webrick.rb +9 -7
- data/lib/asir/uuid.rb +41 -3
- data/lib/asir/version.rb +1 -1
- data/spec/transport_spec.rb +8 -3
- data/spec/uuid_spec.rb +76 -0
- metadata +4 -1
data/.gitignore
CHANGED
data/ChangeLog
CHANGED
@@ -1,5 +1,12 @@
|
|
1
|
-
2012-12-
|
1
|
+
2012-12-29 Kurt A. Stephens <ks.github@kurtstephens.com>
|
2
|
+
|
3
|
+
* v1.2.0: New version: API changes.
|
4
|
+
* Message::State: internal object encapsulates state between #send_message, #receive_message, #send_result, #receive_result.
|
5
|
+
* Callbacks: most callbacks take a MessageResult object instead of Message and/or Result objects.
|
6
|
+
* UUID: Added new_uuid, process_uuid, counter_uuid, thread_uuid as mixin methods.
|
7
|
+
* Identity: Removed deprecated #client, #server attributes, use additional_data.
|
2
8
|
|
9
|
+
2012-12-28 Kurt A. Stephens <ks.github@kurtstephens.com>
|
3
10
|
* v1.1.12: New version.
|
4
11
|
* Rubinius: Rubinius -Xversion=18 and =19 support.
|
5
12
|
* XML: Really removed Coder::XML.
|
data/example/ex18.rb
CHANGED
@@ -9,8 +9,9 @@ begin
|
|
9
9
|
:encoder => ASIR::Coder::Yaml.new(:yaml_options => { :ASCII_8BIT_ok => true }))
|
10
10
|
tcp = ASIR::Transport::TcpSocket.new(:port => 31918,
|
11
11
|
:encoder => ASIR::Coder::Marshal.new)
|
12
|
-
start_server_proc = lambda do | transport,
|
13
|
-
|
12
|
+
start_server_proc = lambda do | transport, message_result |
|
13
|
+
message = message_result.message
|
14
|
+
# $stderr.puts "message = #{message.inspect}"
|
14
15
|
file.send_message(message)
|
15
16
|
server_process do
|
16
17
|
tcp.prepare_server!
|
data/example/ex26.rb
CHANGED
@@ -7,7 +7,7 @@ begin
|
|
7
7
|
Email.asir.transport = t =
|
8
8
|
ASIR::Transport::Thread.new
|
9
9
|
spawned_thread = nil
|
10
|
-
t.after_thread_new = lambda do | transport,
|
10
|
+
t.after_thread_new = lambda do | transport, message_result, thread |
|
11
11
|
spawned_thread = thread
|
12
12
|
$stderr.puts "\n #{$$}: Spawned Thread #{thread.inspect}"
|
13
13
|
end
|
data/example/example_helper.rb
CHANGED
@@ -48,7 +48,12 @@ def server_process &blk
|
|
48
48
|
if ENV['ASIR_JRUBY_SPAWNED']
|
49
49
|
$stderr.puts " spawned server at #{__FILE__}:#{__LINE__}"
|
50
50
|
puts "*** #{$$}: server process"; $stdout.flush
|
51
|
-
|
51
|
+
begin
|
52
|
+
yield
|
53
|
+
rescue ::Exception => exc
|
54
|
+
$stderr.puts "*** #{$$}: service ERROR: #{exc.inspect}\n #{exc.backtrace * " \n"}"
|
55
|
+
raise exc
|
56
|
+
end
|
52
57
|
Process.exit!(0)
|
53
58
|
# dont do client, client is our parent process.
|
54
59
|
else
|
@@ -64,7 +69,12 @@ def server_process &blk
|
|
64
69
|
# $stderr.puts " at #{__FILE__}:#{__LINE__}"
|
65
70
|
$server_pid = Process.fork do
|
66
71
|
puts "*** #{$$}: server process"; $stdout.flush
|
67
|
-
|
72
|
+
begin
|
73
|
+
yield
|
74
|
+
rescue ::Exception => exc
|
75
|
+
$stderr.puts "*** #{$$}: service ERROR: #{exc.inspect}\n #{exc.backtrace * " \n"}"
|
76
|
+
raise exc
|
77
|
+
end
|
68
78
|
end
|
69
79
|
end
|
70
80
|
sleep 1 # wait for server to be ready.
|
data/lib/asir.rb
CHANGED
data/lib/asir/additional_data.rb
CHANGED
@@ -28,19 +28,19 @@ module ASIR
|
|
28
28
|
|
29
29
|
module ModuleMethods
|
30
30
|
# Provide a getter method that delegates to addtional_data[...].
|
31
|
-
def
|
31
|
+
def addit_getter *names
|
32
32
|
names.each do | name |
|
33
33
|
name = name.to_sym
|
34
|
-
define_method(name) { | |
|
34
|
+
define_method(name) { | | self[name] }
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
38
|
# Provide getter and setter methods that delegate to addtional_data[...].
|
39
|
-
def
|
39
|
+
def addit_accessor *names
|
40
40
|
addr_getter *names
|
41
41
|
names.each do | name |
|
42
42
|
name = name.to_sym
|
43
|
-
define_method(:"#{name}=") { | v |
|
43
|
+
define_method(:"#{name}=") { | v | self[name] = v }
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
data/lib/asir/client.rb
CHANGED
@@ -54,8 +54,7 @@ module ASIR
|
|
54
54
|
message = Message.new(@receiver, selector, arguments, block, self)
|
55
55
|
message = @before_send_message.call(message) if @before_send_message
|
56
56
|
@__configure.call(message, self) if @__configure
|
57
|
-
|
58
|
-
result
|
57
|
+
transport.send_message(message) # => result
|
59
58
|
end
|
60
59
|
# Accept all other messages to be encoded and transported to a service.
|
61
60
|
alias :method_missing :send
|
data/lib/asir/identity.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'asir/uuid'
|
2
|
-
require 'thread' # Mutex
|
3
2
|
|
4
3
|
module ASIR
|
5
4
|
# !SLIDE
|
@@ -8,29 +7,14 @@ module ASIR
|
|
8
7
|
module Identity
|
9
8
|
attr_accessor :identifier, :timestamp
|
10
9
|
|
11
|
-
# Optional: Opaque data about the Client that created the Message.
|
12
|
-
attr_accessor :client
|
13
|
-
|
14
|
-
# Optional: Opaque data about the Service that handled the Result.
|
15
|
-
attr_accessor :server
|
16
|
-
|
17
10
|
# Creates a thread-safe unique identifier.
|
18
11
|
def create_identifier!
|
19
|
-
@identifier ||=
|
20
|
-
@@identifier_mutex.synchronize do
|
21
|
-
if @@uuid_pid != $$
|
22
|
-
@@uuid_pid = $$
|
23
|
-
@@uuid = nil
|
24
|
-
end
|
25
|
-
"#{@@counter += 1}-#{@@uuid ||= ::ASIR::UUID.generate}".freeze
|
26
|
-
end
|
12
|
+
@identifier ||= ::ASIR::UUID.counter_uuid
|
27
13
|
end
|
28
|
-
@@counter ||= 0; @@uuid ||= nil; @@uuid_pid = nil; @@identifier_mutex ||= Mutex.new
|
29
14
|
|
30
15
|
# Creates a timestamp.
|
31
16
|
def create_timestamp!
|
32
|
-
@timestamp ||=
|
33
|
-
::Time.now.gmtime
|
17
|
+
@timestamp ||= ::Time.now.gmtime
|
34
18
|
end
|
35
19
|
end
|
36
20
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module ASIR
|
2
|
+
class Message
|
3
|
+
# !SLIDE
|
4
|
+
# Message::State
|
5
|
+
#
|
6
|
+
# Encapsulate the Message, Result and their payloads and other state.
|
7
|
+
# This is passed between Transport#send_request, #receive_request, #send_response, #receive_response.
|
8
|
+
class State
|
9
|
+
include Initialization
|
10
|
+
attr_accessor :message, :result
|
11
|
+
attr_accessor :message_payload, :result_payload
|
12
|
+
attr_accessor :message_opaque, :result_opaque
|
13
|
+
attr_accessor :in_stream, :out_stream
|
14
|
+
attr_accessor :additional_data
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
data/lib/asir/transport.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'time'
|
2
2
|
require 'asir/thread_variable'
|
3
3
|
require 'asir/message/delay'
|
4
|
+
require 'asir/message/state'
|
4
5
|
require 'asir/transport/conduit'
|
5
6
|
|
6
7
|
module ASIR
|
@@ -23,46 +24,44 @@ module ASIR
|
|
23
24
|
# * Send encoded Message.
|
24
25
|
# * Receive decoded Result.
|
25
26
|
def send_message message
|
26
|
-
@message_count ||= 0; @message_count += 1
|
27
|
+
@message_count ||= 0; @message_count += 1 # NOT THREAD-SAFE
|
27
28
|
message.create_timestamp! if needs_message_timestamp? message
|
28
29
|
message.create_identifier! if needs_message_identifier? message
|
29
|
-
@before_send_message.call(self, message) if @before_send_message
|
30
30
|
relative_message_delay! message
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
state = Message::State.new(:message => message, :message_payload => encoder.prepare.encode(message))
|
32
|
+
@before_send_message.call(self, state) if @before_send_message
|
33
|
+
_send_message(state)
|
34
|
+
receive_result(state)
|
34
35
|
end
|
35
36
|
|
36
37
|
# !SLIDE
|
37
38
|
# Transport#receive_message
|
38
39
|
# Receive Message payload from stream.
|
39
|
-
def receive_message
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
if @after_receive_message
|
47
|
-
@after_receive_message.call(self, message)
|
40
|
+
def receive_message state
|
41
|
+
@message_count ||= 0; @message_count += 1 # NOT THREAD-SAFE
|
42
|
+
if received = _receive_message(state)
|
43
|
+
if message = state.message = encoder.prepare.decode(state.message_payload)
|
44
|
+
message.additional_data!.update(state.additional_data) if state.additional_data
|
45
|
+
@after_receive_message.call(self, state) if @after_receive_message
|
46
|
+
self
|
48
47
|
end
|
49
48
|
end
|
50
|
-
req_and_state
|
51
49
|
end
|
52
50
|
# !SLIDE END
|
53
51
|
|
54
52
|
# !SLIDE
|
55
53
|
# Transport#send_result
|
56
54
|
# Send Result to stream.
|
57
|
-
def send_result
|
58
|
-
|
55
|
+
def send_result state
|
56
|
+
result = state.result
|
57
|
+
message = state.message
|
59
58
|
if @one_way && message.block
|
60
59
|
message.block.call(result)
|
61
60
|
else
|
62
|
-
#
|
61
|
+
# Avoid sending back entire Message in Result.
|
63
62
|
result.message = nil unless @coder_needs_result_message
|
64
|
-
result_payload = decoder.prepare.encode(result)
|
65
|
-
_send_result(
|
63
|
+
state.result_payload = decoder.prepare.encode(result)
|
64
|
+
_send_result(state)
|
66
65
|
end
|
67
66
|
end
|
68
67
|
attr_accessor :coder_needs_result_message
|
@@ -75,19 +74,24 @@ module ASIR
|
|
75
74
|
# * Receive Result payload
|
76
75
|
# * Decode Result.
|
77
76
|
# * Extract Result result or exception.
|
78
|
-
|
79
|
-
|
80
|
-
|
77
|
+
# * Invoke Exception or return Result value.
|
78
|
+
def receive_result state
|
79
|
+
value = nil
|
80
|
+
return value unless _receive_result(state)
|
81
|
+
result = state.result ||= decoder.prepare.decode(state.result_payload)
|
82
|
+
message = state.message
|
81
83
|
if result && ! message.one_way
|
84
|
+
result.message = message
|
82
85
|
if exc = result.exception
|
83
86
|
invoker.invoke!(exc, self)
|
84
87
|
else
|
85
88
|
if ! @one_way && message.block
|
86
89
|
message.block.call(result)
|
87
90
|
end
|
88
|
-
result.result
|
91
|
+
value = result.result
|
89
92
|
end
|
90
93
|
end
|
94
|
+
value
|
91
95
|
end
|
92
96
|
# !SLIDE END
|
93
97
|
|
@@ -118,8 +122,8 @@ module ASIR
|
|
118
122
|
# Proc to call with exception, if exception occurs within #serve_message!, but outside
|
119
123
|
# Message#invoke!.
|
120
124
|
#
|
121
|
-
# trans.on_exception.call(trans, exception, :message,
|
122
|
-
# trans.on_exception.call(trans, exception, :result,
|
125
|
+
# trans.on_exception.call(trans, exception, :message, message_state)
|
126
|
+
# trans.on_exception.call(trans, exception, :result, message_state)
|
123
127
|
attr_accessor :on_exception
|
124
128
|
|
125
129
|
attr_accessor :needs_message_identifier, :needs_message_timestamp
|
@@ -139,15 +143,15 @@ module ASIR
|
|
139
143
|
# !SLIDE
|
140
144
|
# Serve a Message.
|
141
145
|
def serve_message! in_stream, out_stream
|
142
|
-
|
146
|
+
state = message_ok = result = result_ok = nil
|
143
147
|
exception = original_exception = unforwardable_exception = nil
|
144
|
-
|
145
|
-
if
|
148
|
+
state = Message::State.new(:in_stream => in_stream, :out_stream => out_stream)
|
149
|
+
if receive_message(state)
|
146
150
|
message_ok = true
|
147
|
-
|
151
|
+
invoke_message!(state)
|
148
152
|
result_ok = true
|
149
153
|
if @after_invoke_message
|
150
|
-
@after_invoke_message.call(self,
|
154
|
+
@after_invoke_message.call(self, state)
|
151
155
|
end
|
152
156
|
self
|
153
157
|
else
|
@@ -156,7 +160,7 @@ module ASIR
|
|
156
160
|
rescue ::Exception => exc
|
157
161
|
exception = original_exception = exc
|
158
162
|
_log [ :message_error, exc ]
|
159
|
-
@on_exception.call(self, exc, :message,
|
163
|
+
@on_exception.call(self, exc, :message, state) if @on_exception
|
160
164
|
ensure
|
161
165
|
begin
|
162
166
|
if message_ok
|
@@ -165,15 +169,15 @@ module ASIR
|
|
165
169
|
when *Error::Unforwardable.unforwardable
|
166
170
|
unforwardable_exception = exception = Error::Unforwardable.new(exception)
|
167
171
|
end
|
168
|
-
result = Result.new(message, nil, exception)
|
172
|
+
state.result = Result.new(state.message, nil, exception)
|
169
173
|
end
|
170
174
|
if out_stream
|
171
|
-
send_result(
|
175
|
+
send_result(state)
|
172
176
|
end
|
173
177
|
end
|
174
178
|
rescue ::Exception => exc
|
175
|
-
_log [ :result_error, exc ]
|
176
|
-
@on_exception.call(self, exc, :result,
|
179
|
+
_log [ :result_error, exc, exc.backtrace ]
|
180
|
+
@on_exception.call(self, exc, :result, state) if @on_exception
|
177
181
|
end
|
178
182
|
raise original_exception if unforwardable_exception
|
179
183
|
end
|
@@ -227,21 +231,25 @@ module ASIR
|
|
227
231
|
end
|
228
232
|
|
229
233
|
# Invokes the Message object, returns a Result object.
|
230
|
-
def invoke_message!
|
231
|
-
result = nil
|
234
|
+
def invoke_message! state
|
232
235
|
Transport.with_attr! :current, self do
|
233
|
-
with_attr! :
|
234
|
-
|
235
|
-
|
236
|
+
with_attr! :message_state, state do
|
237
|
+
with_attr! :message, state.message do
|
238
|
+
wait_for_delay! state.message
|
239
|
+
state.result = invoker.invoke!(state.message, self)
|
236
240
|
# Hook for Exceptions.
|
237
|
-
if @on_result_exception && result.exception
|
238
|
-
@on_result_exception.call(self,
|
241
|
+
if @on_result_exception && state.result.exception
|
242
|
+
@on_result_exception.call(self, state)
|
239
243
|
end
|
240
244
|
end
|
241
245
|
end
|
242
|
-
|
246
|
+
end
|
247
|
+
self
|
243
248
|
end
|
244
|
-
|
249
|
+
|
250
|
+
# The current Message::State.
|
251
|
+
attr_accessor_thread :message_state
|
252
|
+
# The current Message being invoked. DEPRECATED.
|
245
253
|
attr_accessor_thread :message
|
246
254
|
|
247
255
|
# The current active Transport.
|
@@ -9,23 +9,22 @@ module ASIR
|
|
9
9
|
class Broadcast < self
|
10
10
|
include Composite
|
11
11
|
|
12
|
-
def _send_message
|
12
|
+
def _send_message state
|
13
13
|
result = first_exception = nil
|
14
14
|
transports.each do | transport |
|
15
15
|
begin
|
16
|
-
result = transport.send_message(message)
|
16
|
+
result = transport.send_message(state.message)
|
17
17
|
rescue ::Exception => exc
|
18
18
|
first_exception ||= exc
|
19
|
-
_handle_send_message_exception! transport,
|
19
|
+
_handle_send_message_exception! transport, state, exc
|
20
20
|
raise exc unless @continue_on_exception
|
21
21
|
end
|
22
22
|
end
|
23
23
|
if first_exception && @reraise_first_exception
|
24
24
|
raise first_exception
|
25
25
|
end
|
26
|
-
result
|
26
|
+
state.result = Result.new(state.message, result)
|
27
27
|
end
|
28
|
-
|
29
28
|
end
|
30
29
|
# !SLIDE END
|
31
30
|
end
|
@@ -25,15 +25,15 @@ module ASIR
|
|
25
25
|
|
26
26
|
# If paused, queue messages,
|
27
27
|
# Otherwise delegate immediately to #transport.
|
28
|
-
def _send_message
|
28
|
+
def _send_message state
|
29
29
|
return nil if @ignore
|
30
30
|
if paused?
|
31
31
|
@messages_mutex.synchronize do
|
32
|
-
@messages << message
|
32
|
+
@messages << state.message
|
33
33
|
end
|
34
34
|
nil
|
35
35
|
else
|
36
|
-
@transport.send_message(message)
|
36
|
+
@transport.send_message(state.message)
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
@@ -97,7 +97,7 @@ module ASIR
|
|
97
97
|
# Usually used in worker Thread.
|
98
98
|
def process! non_block=false
|
99
99
|
@running = true
|
100
|
-
while @running && message = shift(non_block)
|
100
|
+
while @running && (message = shift(non_block))
|
101
101
|
@transport.send_message(message)
|
102
102
|
end
|
103
103
|
message
|
@@ -5,10 +5,11 @@ module Asir
|
|
5
5
|
# Conduit service support.
|
6
6
|
module Conduit
|
7
7
|
attr_accessor :conduit_options, :conduit_pid
|
8
|
+
|
8
9
|
def start_conduit! options = nil
|
9
|
-
opts =
|
10
|
+
opts = @conduit_options ||= {}
|
11
|
+
opts.update(:fork => true)
|
10
12
|
opts.update(options) if options
|
11
|
-
@conduit_options = opts
|
12
13
|
_log { "start_conduit! #{self}" } if @verbose >= 1
|
13
14
|
in_fork = opts[:fork]
|
14
15
|
raise "already running #{@conduit_pid} #{@conduit_cmd}" if @conduit_pid
|
@@ -19,7 +20,7 @@ module Asir
|
|
19
20
|
raise "Could not exec"
|
20
21
|
end
|
21
22
|
_log { "start_conduit! #{self} started pid=#{@conduit_pid.inspect}" } if @verbose >= 2
|
22
|
-
if pid_file = @conduit_options[:pid_file]
|
23
|
+
if pid_file = (@conduit_options || EMPTY_HASH)[:pid_file]
|
23
24
|
File.open(pid_file, "w") { | fh | fh.puts @conduit_pid }
|
24
25
|
end
|
25
26
|
else
|
@@ -29,7 +30,7 @@ module Asir
|
|
29
30
|
end
|
30
31
|
|
31
32
|
def conduit_pid
|
32
|
-
if ! @conduit_pid and pid_file = @conduit_options[:pid_file]
|
33
|
+
if ! @conduit_pid and pid_file = (@conduit_options || EMPTY_HASH)[:pid_file]
|
33
34
|
@conduit_pid = (File.read(pid_file).to_i rescue nil)
|
34
35
|
end
|
35
36
|
@conduit_pid
|
@@ -37,10 +38,11 @@ module Asir
|
|
37
38
|
|
38
39
|
def stop_conduit! opts = nil
|
39
40
|
if conduit_pid
|
40
|
-
pid_file = @conduit_options[:pid_file]
|
41
41
|
_log { "stop_conduit! #{self} pid=#{@conduit_pid.inspect}" } if @verbose >= 1
|
42
42
|
::Process.kill( (opts && opts[:signal]) || 'TERM', @conduit_pid)
|
43
|
-
|
43
|
+
if pid_file = (@conduit_options || EMPTY_HASH)[:pid_file]
|
44
|
+
::File.unlink(pid_file) rescue nil
|
45
|
+
end
|
44
46
|
::Process.waitpid @conduit_pid
|
45
47
|
end
|
46
48
|
self
|
@@ -52,33 +52,35 @@ module ASIR
|
|
52
52
|
|
53
53
|
# !SLIDE
|
54
54
|
# Sends the encoded Message payload String.
|
55
|
-
def _send_message
|
55
|
+
def _send_message state
|
56
56
|
stream.with_stream! do | io |
|
57
|
-
|
57
|
+
state.in_stream = io
|
58
|
+
_write(state.message_payload, io, state)
|
58
59
|
end
|
59
60
|
end
|
60
61
|
|
61
62
|
# !SLIDE
|
62
63
|
# Receives the encoded Message payload String.
|
63
|
-
def _receive_message
|
64
|
-
|
64
|
+
def _receive_message state
|
65
|
+
state.message_payload = _read(state.in_stream, state)
|
65
66
|
end
|
66
67
|
|
67
68
|
# !SLIDE
|
68
69
|
# Sends the encoded Result payload String.
|
69
|
-
def _send_result
|
70
|
-
unless @one_way || message.one_way
|
71
|
-
|
70
|
+
def _send_result state
|
71
|
+
unless @one_way || state.message.one_way
|
72
|
+
# $stderr.write "\n _send_result #{state.result_payload.inspect}\n\n"
|
73
|
+
_write(state.result_payload, state.out_stream, state)
|
74
|
+
true
|
72
75
|
end
|
73
76
|
end
|
74
77
|
|
75
78
|
# !SLIDE
|
76
79
|
# Receives the encoded Result payload String.
|
77
|
-
def _receive_result
|
78
|
-
unless @one_way || message.one_way
|
79
|
-
|
80
|
-
|
81
|
-
end
|
80
|
+
def _receive_result state
|
81
|
+
unless @one_way || state.message.one_way
|
82
|
+
state.result_payload = _read(state.in_stream, state)
|
83
|
+
true
|
82
84
|
end
|
83
85
|
end
|
84
86
|
|
@@ -115,6 +117,7 @@ module ASIR
|
|
115
117
|
end
|
116
118
|
|
117
119
|
def serve_connection!
|
120
|
+
_log { "serve_connection!: accepting connection" } if @verbose >= 2
|
118
121
|
in_stream, out_stream = _server_accept_connection! @server
|
119
122
|
_log { "serve_connection!: connected #{in_stream} #{out_stream}" } if @verbose >= 1
|
120
123
|
_server_serve_stream! in_stream, out_stream
|
@@ -19,29 +19,27 @@ module ASIR
|
|
19
19
|
self.needs_message_identifier = true
|
20
20
|
end
|
21
21
|
|
22
|
-
def _send_message
|
22
|
+
def _send_message state
|
23
23
|
if @before_message_save
|
24
|
-
@before_message_save.call(self,
|
24
|
+
@before_message_save.call(self, state)
|
25
25
|
end
|
26
|
-
message_payload.save!
|
26
|
+
state.message_payload.save!
|
27
27
|
# message[:database_id] ||= message_payload.database_id
|
28
28
|
if @after_message_save
|
29
|
-
@after_message_save.call(self,
|
29
|
+
@after_message_save.call(self, state)
|
30
30
|
end
|
31
|
-
nil # message_state
|
32
31
|
end
|
33
32
|
|
34
|
-
def _send_result
|
35
|
-
return if one_way? or message.one_way?
|
33
|
+
def _send_result state
|
34
|
+
return if one_way? or state.message.one_way?
|
36
35
|
if @before_result_save
|
37
|
-
@before_result_save.call(self,
|
36
|
+
@before_result_save.call(self, state)
|
38
37
|
end
|
39
|
-
result_payload.save!
|
38
|
+
state.result_payload.save!
|
40
39
|
result[:database_id] = result_payload.database_id
|
41
40
|
if @after_result_save
|
42
|
-
@after_result_save.call(self,
|
41
|
+
@after_result_save.call(self, state)
|
43
42
|
end
|
44
|
-
nil
|
45
43
|
end
|
46
44
|
end
|
47
45
|
end
|
@@ -14,14 +14,9 @@ module ASIR
|
|
14
14
|
# Proc to call(transport, message) when #send_message fails with no recourse.
|
15
15
|
attr_accessor :on_failed_message
|
16
16
|
|
17
|
-
# Return the subTransports
|
18
|
-
def _receive_result
|
19
|
-
|
20
|
-
end
|
21
|
-
|
22
|
-
# Return the subTransports#send_message result unmodified from #_send_message.
|
23
|
-
def receive_result message, opaque_result
|
24
|
-
opaque_result
|
17
|
+
# Return the subTransports' result unmodified from #_send_message.
|
18
|
+
def _receive_result state
|
19
|
+
true
|
25
20
|
end
|
26
21
|
|
27
22
|
def needs_message_identifier? message
|
@@ -40,10 +35,10 @@ module ASIR
|
|
40
35
|
end
|
41
36
|
|
42
37
|
# Called from within _send_message rescue.
|
43
|
-
def _handle_send_message_exception! transport,
|
44
|
-
_log { [ :send_message, :transport_failed, exc ] }
|
45
|
-
(message[:transport_exceptions] ||= [ ]) << "#{exc.inspect}: #{exc.backtrace.first}"
|
46
|
-
@on_send_message_exception.call(self,
|
38
|
+
def _handle_send_message_exception! transport, state, exc
|
39
|
+
_log { [ :send_message, :transport_failed, exc, exc.backtrace ] }
|
40
|
+
(state.message[:transport_exceptions] ||= [ ]) << "#{exc.inspect}: #{exc.backtrace.first}"
|
41
|
+
@on_send_message_exception.call(self, state, exc) if @on_send_message_exception
|
47
42
|
self
|
48
43
|
end
|
49
44
|
end
|
data/lib/asir/transport/demux.rb
CHANGED
@@ -7,16 +7,16 @@ module ASIR
|
|
7
7
|
class Fallback < self
|
8
8
|
include Composite
|
9
9
|
|
10
|
-
def _send_message
|
10
|
+
def _send_message state
|
11
11
|
result = sent = first_exception = nil
|
12
12
|
transports.each do | transport |
|
13
13
|
begin
|
14
|
-
result = transport.send_message(message)
|
14
|
+
result = transport.send_message(state.message)
|
15
15
|
sent = true
|
16
16
|
break
|
17
17
|
rescue ::Exception => exc
|
18
18
|
first_exception ||= exc
|
19
|
-
_handle_send_message_exception! transport,
|
19
|
+
_handle_send_message_exception! transport, state, exc
|
20
20
|
end
|
21
21
|
end
|
22
22
|
unless sent
|
@@ -25,7 +25,7 @@ module ASIR
|
|
25
25
|
end
|
26
26
|
raise FallbackError, "fallback failed"
|
27
27
|
end
|
28
|
-
result
|
28
|
+
state.result = Result.new(state.message, result)
|
29
29
|
end
|
30
30
|
class FallbackError < Error; end
|
31
31
|
end
|
data/lib/asir/transport/file.rb
CHANGED
@@ -15,24 +15,24 @@ module ASIR
|
|
15
15
|
def initialize opts = nil; @one_way = true; super; end
|
16
16
|
|
17
17
|
# Writes a Message payload String.
|
18
|
-
def _send_message
|
19
|
-
_write
|
18
|
+
def _send_message state
|
19
|
+
_write(state.message_payload, state.out_stream || stream, state)
|
20
20
|
ensure
|
21
21
|
close if file && ::File.pipe?(file)
|
22
22
|
end
|
23
23
|
|
24
24
|
# Returns a Message payload String.
|
25
|
-
def _receive_message
|
26
|
-
|
25
|
+
def _receive_message state
|
26
|
+
state.message_payload = _read(state.in_stream || stream, state)
|
27
27
|
end
|
28
28
|
|
29
29
|
# one-way; no Result.
|
30
|
-
def _send_result
|
30
|
+
def _send_result state
|
31
31
|
nil
|
32
32
|
end
|
33
33
|
|
34
34
|
# one-way; no Result.
|
35
|
-
def _receive_result
|
35
|
+
def _receive_result state
|
36
36
|
nil
|
37
37
|
end
|
38
38
|
|
@@ -63,7 +63,6 @@ module ASIR
|
|
63
63
|
# Named Pipe Server
|
64
64
|
|
65
65
|
def prepare_server!
|
66
|
-
# _log [ :prepare_pipe_server!, file ]
|
67
66
|
unless ::File.exist? file
|
68
67
|
system(cmd = "mkfifo #{file.inspect}") or raise "cannot run #{cmd.inspect}"
|
69
68
|
::File.chmod(perms, file) rescue nil if perms
|
@@ -72,7 +71,6 @@ module ASIR
|
|
72
71
|
alias :prepare_pipe_server! :prepare_server!
|
73
72
|
|
74
73
|
def run_server!
|
75
|
-
# _log [ :run_pipe_server!, file ]
|
76
74
|
with_server_signals! do
|
77
75
|
@running = true
|
78
76
|
while @running
|
data/lib/asir/transport/http.rb
CHANGED
@@ -30,18 +30,23 @@ module ASIR
|
|
30
30
|
|
31
31
|
# Send the Message payload String using HTTP POST.
|
32
32
|
# Returns the HTTPClient::Request response object.
|
33
|
-
def _send_message
|
33
|
+
def _send_message state
|
34
34
|
client.with_stream! do | client |
|
35
|
-
|
35
|
+
state.in_stream =
|
36
|
+
client.post(message_uri(state), state.message_payload)
|
36
37
|
end
|
37
38
|
end
|
38
39
|
|
40
|
+
# Subclasses can override.
|
41
|
+
def message_uri state
|
42
|
+
state.message[:uri] || uri
|
43
|
+
end
|
44
|
+
|
39
45
|
# Recieve the Result payload String from the opaque
|
40
46
|
# HTTPClient::Request response object returned from #_send_message.
|
41
|
-
def _receive_result
|
42
|
-
|
43
|
-
|
44
|
-
http_result_message.content.to_s
|
47
|
+
def _receive_result state
|
48
|
+
state.result_payload =
|
49
|
+
state.in_stream.content.to_s
|
45
50
|
end
|
46
51
|
|
47
52
|
CONTENT_TYPE = 'Content-Type'.freeze
|
data/lib/asir/transport/local.rb
CHANGED
@@ -6,14 +6,16 @@ module ASIR
|
|
6
6
|
# Send Message to same process.
|
7
7
|
# Requires Identity Coder.
|
8
8
|
class Local < self
|
9
|
-
#
|
10
|
-
def _send_message
|
11
|
-
invoke_message!(
|
9
|
+
# Capture Result object after invoking Message.
|
10
|
+
def _send_message state
|
11
|
+
invoke_message!(state)
|
12
|
+
self
|
12
13
|
end
|
13
14
|
|
14
|
-
#
|
15
|
-
def _receive_result
|
16
|
-
|
15
|
+
# Result object was captured in #_send_message.
|
16
|
+
def _receive_result state
|
17
|
+
state.result_payload = state.result
|
18
|
+
self
|
17
19
|
end
|
18
20
|
end
|
19
21
|
# !SLIDE END
|
data/lib/asir/transport/null.rb
CHANGED
@@ -14,7 +14,7 @@ module ASIR
|
|
14
14
|
HEADER = "# asir_payload_size: "
|
15
15
|
FOOTER = "\n# asir_payload_end"
|
16
16
|
|
17
|
-
def _write payload, stream,
|
17
|
+
def _write payload, stream, state
|
18
18
|
stream.write HEADER
|
19
19
|
stream.puts payload.size
|
20
20
|
stream.write payload
|
@@ -23,7 +23,7 @@ module ASIR
|
|
23
23
|
stream
|
24
24
|
end
|
25
25
|
|
26
|
-
def _read stream,
|
26
|
+
def _read stream, state
|
27
27
|
size = /\d+$/.match(stream.readline.chomp)[0].to_i # HEADER (size)
|
28
28
|
payload = stream.read(size)
|
29
29
|
stream.readline # FOOTER
|
data/lib/asir/transport/rack.rb
CHANGED
@@ -7,17 +7,16 @@ module ASIR
|
|
7
7
|
# Rack Transport
|
8
8
|
class Rack < HTTP
|
9
9
|
# Receive the Message payload String from the Rack::Request object.
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
[ body, rack_req_res ]
|
10
|
+
def _receive_message state
|
11
|
+
rack_request = state.in_stream
|
12
|
+
state.message_payload = rack_request.body.read
|
14
13
|
end
|
15
14
|
|
16
15
|
# Send the Result payload String in the Rack::Response object as application/binary.
|
17
|
-
def _send_result
|
18
|
-
rack_response =
|
16
|
+
def _send_result state
|
17
|
+
rack_response = state.out_stream
|
19
18
|
rack_response[CONTENT_TYPE] = APPLICATION_BINARY
|
20
|
-
rack_response.write result_payload
|
19
|
+
rack_response.write state.result_payload
|
21
20
|
end
|
22
21
|
|
23
22
|
# Constructs a Rackable App from this Transport.
|
@@ -41,8 +40,7 @@ module ASIR
|
|
41
40
|
def call(env)
|
42
41
|
rq = ::Rack::Request.new(env)
|
43
42
|
rs = ::Rack::Response.new
|
44
|
-
|
45
|
-
serve_message! rack_rq_rs, rack_rq_rs
|
43
|
+
serve_message! rq, rs
|
46
44
|
rs.finish # => [ status, header, rbody ]
|
47
45
|
end
|
48
46
|
|
data/lib/asir/transport/retry.rb
CHANGED
@@ -13,19 +13,20 @@ module ASIR
|
|
13
13
|
# Proc to call(transport, message) before retry.
|
14
14
|
attr_accessor :before_retry
|
15
15
|
|
16
|
-
def _send_message
|
16
|
+
def _send_message state
|
17
17
|
first_exception = nil
|
18
18
|
with_retry do | action, data |
|
19
19
|
case action
|
20
20
|
when :try
|
21
|
-
transport.send_message(message)
|
21
|
+
result = transport.send_message(state.message)
|
22
|
+
state.result = Result.new(state.message, result)
|
22
23
|
when :rescue #, exc
|
23
24
|
first_exception ||= data
|
24
|
-
_handle_send_message_exception! transport,
|
25
|
+
_handle_send_message_exception! transport, state, data
|
25
26
|
when :retry #, exc
|
26
|
-
before_retry.call(self,
|
27
|
+
before_retry.call(self, state) if before_retry
|
27
28
|
when :failed
|
28
|
-
@on_failed_message.call(self,
|
29
|
+
@on_failed_message.call(self, state) if @on_failed_message
|
29
30
|
if first_exception && @reraise_first_exception
|
30
31
|
$! = first_exception
|
31
32
|
raise
|
@@ -11,18 +11,19 @@ module ASIR
|
|
11
11
|
@one_way = true; super
|
12
12
|
end
|
13
13
|
|
14
|
-
def _send_message
|
14
|
+
def _send_message state
|
15
15
|
Process.fork do
|
16
|
-
|
16
|
+
super
|
17
|
+
send_result(state)
|
17
18
|
end
|
18
19
|
end
|
19
20
|
|
20
21
|
# one-way; no Result
|
21
|
-
def _receive_result
|
22
|
+
def _receive_result state
|
22
23
|
end
|
23
24
|
|
24
25
|
# one-way; no Result
|
25
|
-
def _send_result
|
26
|
+
def _send_result state
|
26
27
|
end
|
27
28
|
end
|
28
29
|
# !SLIDE END
|
@@ -9,14 +9,14 @@ module ASIR
|
|
9
9
|
# !SLIDE
|
10
10
|
# TCP Socket Client
|
11
11
|
def _client_connect!
|
12
|
-
sock = TCPSocket.open(host, port)
|
12
|
+
sock = ::TCPSocket.open(host, port)
|
13
13
|
end
|
14
14
|
|
15
15
|
# !SLIDE
|
16
16
|
# TCP Socket Server
|
17
17
|
def _server!
|
18
|
-
@server = TCPServer.open(port)
|
19
|
-
@server.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, false)
|
18
|
+
@server = ::TCPServer.open(port)
|
19
|
+
@server.setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_KEEPALIVE, false)
|
20
20
|
end
|
21
21
|
|
22
22
|
def _server_accept_connection! server
|
@@ -24,8 +24,8 @@ module ASIR
|
|
24
24
|
[ socket, socket ] # Use same socket for in_stream and out_stream
|
25
25
|
end
|
26
26
|
|
27
|
-
def _server_close_connection!
|
28
|
-
|
27
|
+
def _server_close_connection! in_stream, out_stream
|
28
|
+
in_stream.close rescue nil
|
29
29
|
end
|
30
30
|
end
|
31
31
|
# !SLIDE END
|
@@ -12,7 +12,7 @@ module ASIR
|
|
12
12
|
# Defaults to ::Thread.
|
13
13
|
attr_accessor :thread_class
|
14
14
|
|
15
|
-
# Callback: call(self,
|
15
|
+
# Callback: call(self, MessageState, thr).
|
16
16
|
attr_accessor :after_thread_new
|
17
17
|
|
18
18
|
def initialize *args
|
@@ -20,20 +20,26 @@ module ASIR
|
|
20
20
|
@one_way = true; super
|
21
21
|
end
|
22
22
|
|
23
|
-
def _send_message
|
23
|
+
def _send_message state
|
24
24
|
thr = thread_class.new do
|
25
|
-
|
25
|
+
super
|
26
|
+
send_result(state)
|
26
27
|
end
|
27
|
-
|
28
|
+
state.in_stream = thr
|
29
|
+
@after_thread_new.call(self, state, thr) if @after_thread_new
|
28
30
|
thr
|
29
31
|
end
|
30
32
|
|
31
33
|
# one-way; no Result
|
32
|
-
def _receive_result
|
34
|
+
def _receive_result state
|
33
35
|
end
|
34
36
|
|
35
37
|
# one-way; no Result
|
36
|
-
def _send_result
|
38
|
+
def _send_result state
|
39
|
+
end
|
40
|
+
|
41
|
+
# one-may; no Result
|
42
|
+
def receive_result state
|
37
43
|
end
|
38
44
|
end
|
39
45
|
# !SLIDE END
|
@@ -9,16 +9,18 @@ module ASIR
|
|
9
9
|
|
10
10
|
# Server-side: WEBrick
|
11
11
|
|
12
|
-
# Receive the Message payload
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
# Receive the Message payload from the HTTP Message body.
|
13
|
+
def _receive_message state
|
14
|
+
http_message = state.in_stream
|
15
|
+
state.message_payload = http_message.body
|
16
|
+
state.message_opaque = http_message
|
16
17
|
end
|
17
18
|
|
18
|
-
# Send the Result payload
|
19
|
-
def _send_result
|
19
|
+
# Send the Result payload in the HTTP Response body as application/binary.
|
20
|
+
def _send_result state
|
21
|
+
http_result = state.out_stream
|
20
22
|
http_result[CONTENT_TYPE] = APPLICATION_BINARY
|
21
|
-
http_result.body = result_payload
|
23
|
+
http_result.body = state.result_payload
|
22
24
|
end
|
23
25
|
|
24
26
|
def prepare_server! opts = { }
|
data/lib/asir/uuid.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
1
3
|
module ASIR
|
2
4
|
# Provides an RFC4122-compliant random (version 4) UUID service.
|
3
5
|
module UUID
|
@@ -13,19 +15,55 @@ module UUID
|
|
13
15
|
PROC_SYS_FILE = "/proc/sys/kernel/random/uuid".freeze
|
14
16
|
case
|
15
17
|
when File.exist?(PROC_SYS_FILE)
|
16
|
-
def
|
18
|
+
def new_uuid
|
17
19
|
File.read(PROC_SYS_FILE).chomp!
|
18
20
|
end
|
19
21
|
when (gem 'uuid' rescue nil)
|
20
22
|
require 'uuid'
|
21
|
-
def
|
23
|
+
def new_uuid
|
22
24
|
::UUID.generate
|
23
25
|
end
|
24
26
|
else
|
25
|
-
def
|
27
|
+
def new_uuid
|
26
28
|
raise "Unimplemented"
|
27
29
|
end
|
28
30
|
end
|
31
|
+
UUID_REGEX = /\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\Z/i
|
32
|
+
|
33
|
+
def process_uuid
|
34
|
+
@@process_uuid_mutex.synchronize do
|
35
|
+
if @@pid != $$
|
36
|
+
@@pid = $$
|
37
|
+
@@process_uuid = nil
|
38
|
+
end
|
39
|
+
@@process_uuid ||= new_uuid
|
40
|
+
end
|
41
|
+
end
|
42
|
+
@@pid = @@process_uuid = nil
|
43
|
+
@@process_uuid_mutex = Mutex.new
|
44
|
+
|
45
|
+
def counter_uuid
|
46
|
+
i = @@counter_mutex.synchronize do
|
47
|
+
@@counter += 1
|
48
|
+
end
|
49
|
+
"#{i}-#{process_uuid}"
|
50
|
+
end
|
51
|
+
@@counter ||= 0
|
52
|
+
@@counter_mutex = Mutex.new
|
53
|
+
COUNTER_UUID_REGEX = /\A[0-9]+-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\Z/i
|
54
|
+
|
55
|
+
# Returns a unique counter_uuid for a Thread.
|
56
|
+
# thr defaults to Thread.current.
|
57
|
+
def thread_uuid thr = nil
|
58
|
+
thr ||= Thread.current
|
59
|
+
thr[:'ASIR::UUID.thread_uuid'] || @@thread_uuid_mutex.synchronize do
|
60
|
+
thr[:'ASIR::UUID.thread_uuid'] = counter_uuid
|
61
|
+
end
|
62
|
+
end
|
63
|
+
@@thread_uuid_mutex = Mutex.new
|
64
|
+
|
65
|
+
extend self
|
66
|
+
alias :generate :new_uuid # DEPRECATED
|
29
67
|
end
|
30
68
|
end
|
31
69
|
|
data/lib/asir/version.rb
CHANGED
data/spec/transport_spec.rb
CHANGED
@@ -40,10 +40,10 @@ describe "ASIR::Transport" do
|
|
40
40
|
end
|
41
41
|
|
42
42
|
it 'should handle on_result_exception callbacks' do
|
43
|
-
_transport,
|
44
|
-
p = lambda do | transport,
|
43
|
+
_transport, _message_result = nil, nil
|
44
|
+
p = lambda do | transport, message_result |
|
45
45
|
_transport = transport
|
46
|
-
|
46
|
+
_message_result = message_result
|
47
47
|
end
|
48
48
|
transport.on_result_exception = p
|
49
49
|
|
@@ -71,12 +71,17 @@ describe "ASIR::Transport" do
|
|
71
71
|
|
72
72
|
_transport.should == object.transport
|
73
73
|
|
74
|
+
_result = _message_result.result
|
74
75
|
_result.class.should == ASIR::Result
|
75
76
|
_result.object_id.should == result.object_id
|
76
77
|
|
77
78
|
_result.message.class.should == ASIR::Message
|
78
79
|
_result.message.object_id.should == result.message.object_id
|
79
80
|
_result.exception.should == exc
|
81
|
+
|
82
|
+
_message = _message_result.message
|
83
|
+
_message.object_id.should == _message_result.message.object_id
|
84
|
+
|
80
85
|
end
|
81
86
|
end
|
82
87
|
|
data/spec/uuid_spec.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'asir/uuid'
|
2
|
+
|
3
|
+
describe "ASIR::UUID" do
|
4
|
+
attr_accessor :u
|
5
|
+
before { @u = ASIR::UUID }
|
6
|
+
|
7
|
+
it 'should return a UUID from #new_uuid.' do
|
8
|
+
x = u.new_uuid
|
9
|
+
x.should =~ ASIR::UUID::UUID_REGEX
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should return unique result from #new_uuid.' do
|
13
|
+
a = [ ]
|
14
|
+
10.times do
|
15
|
+
x = u.new_uuid
|
16
|
+
x.should =~ ASIR::UUID::UUID_REGEX
|
17
|
+
a << u.new_uuid
|
18
|
+
end
|
19
|
+
a.uniq.size.should == 10
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should single unique result per process from #process_uuid.' do
|
23
|
+
a = [ ]
|
24
|
+
10.times do
|
25
|
+
x = u.process_uuid
|
26
|
+
x.should =~ ASIR::UUID::UUID_REGEX
|
27
|
+
a << u.process_uuid
|
28
|
+
a << u.generate
|
29
|
+
end
|
30
|
+
a.uniq.size.should == 11
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should single unique result per process from #counter_uuid.' do
|
34
|
+
a = [ ]
|
35
|
+
10.times do
|
36
|
+
x = u.counter_uuid
|
37
|
+
x.should =~ ASIR::UUID::COUNTER_UUID_REGEX
|
38
|
+
a << x
|
39
|
+
a << u.process_uuid
|
40
|
+
a << u.generate
|
41
|
+
end
|
42
|
+
a.uniq.size.should == 21
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should single unique result per Thread from #thread_uuid.' do
|
46
|
+
a = [ ]
|
47
|
+
10.times do
|
48
|
+
x = u.thread_uuid
|
49
|
+
x.should =~ ASIR::UUID::COUNTER_UUID_REGEX
|
50
|
+
a << x
|
51
|
+
a << u.generate
|
52
|
+
a << u.process_uuid
|
53
|
+
end
|
54
|
+
a.uniq.size.should == 12
|
55
|
+
|
56
|
+
a = [ ]
|
57
|
+
b = [ ]
|
58
|
+
t1 = Thread.current
|
59
|
+
t2 = Thread.new do
|
60
|
+
10.times do
|
61
|
+
b << u.thread_uuid(t1)
|
62
|
+
b << u.thread_uuid(t2)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
10.times do
|
66
|
+
a << u.thread_uuid(t1)
|
67
|
+
a << u.thread_uuid(t2)
|
68
|
+
end
|
69
|
+
|
70
|
+
t2.join
|
71
|
+
c = a + b
|
72
|
+
c.uniq.size.should == 2
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: asir
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -221,6 +221,7 @@ files:
|
|
221
221
|
- lib/asir/main.rb
|
222
222
|
- lib/asir/message.rb
|
223
223
|
- lib/asir/message/delay.rb
|
224
|
+
- lib/asir/message/state.rb
|
224
225
|
- lib/asir/object_resolving.rb
|
225
226
|
- lib/asir/poll_throttle.rb
|
226
227
|
- lib/asir/result.rb
|
@@ -264,6 +265,7 @@ files:
|
|
264
265
|
- spec/thread_pool_spec.rb
|
265
266
|
- spec/thread_variable_spec.rb
|
266
267
|
- spec/transport_spec.rb
|
268
|
+
- spec/uuid_spec.rb
|
267
269
|
- spec/yaml_spec.rb
|
268
270
|
- stylesheets/slides.css
|
269
271
|
homepage: http://github.com/kstephens/abstracting_services_in_ruby
|
@@ -303,4 +305,5 @@ test_files:
|
|
303
305
|
- spec/thread_pool_spec.rb
|
304
306
|
- spec/thread_variable_spec.rb
|
305
307
|
- spec/transport_spec.rb
|
308
|
+
- spec/uuid_spec.rb
|
306
309
|
- spec/yaml_spec.rb
|