asir 1.0.1 → 1.0.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.
- data/VERSION +1 -1
- data/asir.gemspec +9 -1
- data/lib/asir/error.rb +8 -1
- data/lib/asir/result.rb +6 -0
- data/lib/asir/transport.rb +2 -5
- data/lib/asir/transport/beanstalk.rb +1 -0
- data/lib/asir/transport/broadcast.rb +2 -3
- data/lib/asir/transport/conduit.rb +3 -2
- data/lib/asir/transport/fallback.rb +1 -2
- data/lib/asir/transport/resque.rb +15 -13
- data/lib/asir/transport/stream.rb +2 -1
- data/lib/asir/version.rb +1 -1
- data/spec/resque_spec.rb +173 -0
- metadata +116 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.4
|
data/asir.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{asir}
|
5
|
-
s.version = "1.0.
|
5
|
+
s.version = "1.0.4"
|
6
6
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
7
7
|
s.authors = ["Kurt Stephens"]
|
8
8
|
s.date = %q{2012-04-03}
|
@@ -20,6 +20,14 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.summary = %q{Abstracting Services in Ruby}
|
21
21
|
s.test_files = `git ls-files spec`.split("\n")
|
22
22
|
|
23
|
+
s.add_dependency "uuid", "~> 2.3.5"
|
24
|
+
s.add_dependency "redis", "~> 3.0.2"
|
25
|
+
s.add_dependency "resque", "~> 1.23.0"
|
26
|
+
s.add_dependency "httpclient", "~> 2.3.0"
|
27
|
+
s.add_dependency "libxml-ruby", "~> 2.3.3"
|
28
|
+
s.add_dependency "rack", "~> 1.4.1"
|
29
|
+
s.add_dependency "zmq", "~> 2.1.4"
|
30
|
+
|
23
31
|
if s.respond_to? :specification_version then
|
24
32
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
25
33
|
s.specification_version = 3
|
data/lib/asir/error.rb
CHANGED
@@ -31,7 +31,14 @@ module ASIR
|
|
31
31
|
end
|
32
32
|
def self.unforwardable; @@unforwardable; end
|
33
33
|
def self.unforwardable= x; @@unforwardable = x; end
|
34
|
-
@@unforwardable ||= [
|
34
|
+
@@unforwardable ||= [
|
35
|
+
::SystemExit,
|
36
|
+
::SystemStackError,
|
37
|
+
::NoMemoryError,
|
38
|
+
::Interrupt,
|
39
|
+
::SignalException,
|
40
|
+
Error::Terminate,
|
41
|
+
]
|
35
42
|
end
|
36
43
|
end
|
37
44
|
end
|
data/lib/asir/result.rb
CHANGED
data/lib/asir/transport.rb
CHANGED
@@ -37,17 +37,14 @@ module ASIR
|
|
37
37
|
# Transport#receive_message
|
38
38
|
# Receive Message payload from stream.
|
39
39
|
def receive_message stream
|
40
|
+
# $stderr.puts " #{$$} #{self} receive_message #{stream}"
|
40
41
|
@message_count ||= 0; @message_count += 1
|
41
42
|
additional_data = { }
|
42
43
|
if req_and_state = _receive_message(stream, additional_data)
|
43
44
|
message = req_and_state[0] = encoder.dup.decode(req_and_state.first)
|
44
45
|
message.additional_data!.update(additional_data) if message
|
45
46
|
if @after_receive_message
|
46
|
-
|
47
|
-
@after_receive_message.call(self, message)
|
48
|
-
rescue ::Exception => exc
|
49
|
-
_log { [ :receive_message, :after_receive_message, :exception, exc ] }
|
50
|
-
end
|
47
|
+
@after_receive_message.call(self, message)
|
51
48
|
end
|
52
49
|
end
|
53
50
|
req_and_state
|
@@ -17,12 +17,11 @@ module ASIR
|
|
17
17
|
rescue ::Exception => exc
|
18
18
|
first_exception ||= exc
|
19
19
|
_handle_send_message_exception! transport, message, exc
|
20
|
-
raise unless @continue_on_exception
|
20
|
+
raise exc unless @continue_on_exception
|
21
21
|
end
|
22
22
|
end
|
23
23
|
if first_exception && @reraise_first_exception
|
24
|
-
|
25
|
-
raise
|
24
|
+
raise first_exception
|
26
25
|
end
|
27
26
|
result
|
28
27
|
end
|
@@ -23,9 +23,10 @@ module Asir
|
|
23
23
|
self
|
24
24
|
end
|
25
25
|
|
26
|
-
def stop_conduit!
|
26
|
+
def stop_conduit! opts = nil
|
27
27
|
if @conduit_pid
|
28
|
-
|
28
|
+
_log { "stop_conduit! #{self} pid=#{@conduit_pid.inspect}" } if @verbose >= 1
|
29
|
+
::Process.kill( (opts && opts[:signal]) || 'TERM', @conduit_pid)
|
29
30
|
::Process.waitpid @conduit_pid
|
30
31
|
# File.unlink @redis_conf
|
31
32
|
end
|
@@ -16,10 +16,6 @@ module ASIR
|
|
16
16
|
@scheme_default = 'redis'.freeze
|
17
17
|
super
|
18
18
|
self.one_way = true
|
19
|
-
# Reraise exception, let Resque::Worker handle it.
|
20
|
-
@on_exeception ||= lambda do | trans, exc, type, message |
|
21
|
-
raise exc, exc.backtrace
|
22
|
-
end
|
23
19
|
end
|
24
20
|
|
25
21
|
# !SLIDE
|
@@ -34,6 +30,7 @@ module ASIR
|
|
34
30
|
# !SLIDE
|
35
31
|
# Resque server (worker).
|
36
32
|
def _server!
|
33
|
+
# $stderr.puts " #{$$} #{self} _server!"
|
37
34
|
resque_connect!
|
38
35
|
resque_worker
|
39
36
|
rescue ::Exception => exc
|
@@ -52,7 +49,7 @@ module ASIR
|
|
52
49
|
|
53
50
|
def _send_message message, message_payload
|
54
51
|
stream.with_stream! do | io | # Force connect
|
55
|
-
$stderr.puts " #{self} _send_message #{message_payload.inspect} to queue=#{queue.inspect} as #{self.class} :process_job" if @verbose >= 2
|
52
|
+
$stderr.puts " #{$$} #{self} _send_message #{message_payload.inspect} to queue=#{queue.inspect} as #{self.class} :process_job" if @verbose >= 2
|
56
53
|
::Resque.enqueue_to(queue, self.class, message_payload)
|
57
54
|
end
|
58
55
|
end
|
@@ -107,9 +104,9 @@ module ASIR
|
|
107
104
|
save = Thread.current[:asir_transport_resque_instance]
|
108
105
|
Thread.current[:asir_transport_resque_instance] = self
|
109
106
|
poll_throttle throttle do
|
110
|
-
|
107
|
+
$stderr.puts " #{$$} #{self} serve_stream_message!: resque_worker = #{resque_worker} on queues #{resque_worker.queues}" if @verbose >= 3
|
111
108
|
if job = resque_worker.reserve
|
112
|
-
$stderr.puts " #{self} serve_stream_message! job=#{job.class}:#{job.inspect}" if @verbose >= 2
|
109
|
+
$stderr.puts " #{$$} #{self} serve_stream_message! job=#{job.class}:#{job.inspect}" if @verbose >= 2
|
113
110
|
resque_worker.process(job)
|
114
111
|
end
|
115
112
|
job
|
@@ -128,7 +125,7 @@ module ASIR
|
|
128
125
|
end
|
129
126
|
|
130
127
|
def _receive_message payload, additional_data # is actual payload
|
131
|
-
# $stderr.puts " #{self} _receive_message payload=#{payload.inspect}"
|
128
|
+
# $stderr.puts " #{$$} #{self} _receive_message payload=#{payload.inspect}"
|
132
129
|
[ payload, nil ]
|
133
130
|
end
|
134
131
|
|
@@ -145,12 +142,13 @@ module ASIR
|
|
145
142
|
end
|
146
143
|
|
147
144
|
def resque_connect!
|
145
|
+
@redis_config = {
|
146
|
+
:host => host,
|
147
|
+
:port => port,
|
148
|
+
:thread_safe => true,
|
149
|
+
}
|
148
150
|
@redis =
|
149
|
-
::Redis.new(
|
150
|
-
:host => address || '127.0.0.1',
|
151
|
-
:port => port,
|
152
|
-
:thread_safe => true,
|
153
|
-
})
|
151
|
+
::Redis.new(@redis_config)
|
154
152
|
if namespace_
|
155
153
|
::Resque.redis =
|
156
154
|
@redis =
|
@@ -188,6 +186,10 @@ module ASIR
|
|
188
186
|
worker.unregister_worker
|
189
187
|
end
|
190
188
|
self
|
189
|
+
rescue Redis::CannotConnectError
|
190
|
+
# This error is not actionable since server
|
191
|
+
# is stopping.
|
192
|
+
nil
|
191
193
|
end
|
192
194
|
|
193
195
|
#########################################
|
data/lib/asir/version.rb
CHANGED
data/spec/resque_spec.rb
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'redis'
|
3
|
+
gem 'resque'
|
4
|
+
require 'asir'
|
5
|
+
require 'asir/transport/resque'
|
6
|
+
require 'asir/coder/marshal'
|
7
|
+
|
8
|
+
describe "ASIR::Transport::Resque" do
|
9
|
+
it "should process and stop! gracefully" do
|
10
|
+
with_cleanup! do
|
11
|
+
create_transport!
|
12
|
+
start_conduit!; sleep 1
|
13
|
+
start_client!
|
14
|
+
|
15
|
+
message_count = 0
|
16
|
+
transport.after_receive_message = lambda do | t, message |
|
17
|
+
$stderr.write ">#{message_count += 1}" if verbose
|
18
|
+
if message_count >= 5
|
19
|
+
t.stop!
|
20
|
+
end
|
21
|
+
end
|
22
|
+
start_server!
|
23
|
+
|
24
|
+
message_count.should == 5
|
25
|
+
exceptions.should == [ ]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should bubble up Redis::CannotConnectError if redis is not running" do
|
30
|
+
with_cleanup! do
|
31
|
+
create_transport!
|
32
|
+
message_count = 0
|
33
|
+
lambda do
|
34
|
+
transport.after_receive_message = lambda do | t, message |
|
35
|
+
$stderr.write ">#{message_count += 1}" if verbose
|
36
|
+
if message_count >= 10
|
37
|
+
t.stop!
|
38
|
+
end
|
39
|
+
end
|
40
|
+
start_server!
|
41
|
+
end.should raise_error(Redis::CannotConnectError)
|
42
|
+
message_count.should == 0
|
43
|
+
exceptions.should == [ ]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should bubble up dropped connection error" do
|
48
|
+
with_cleanup! do
|
49
|
+
create_transport!
|
50
|
+
start_conduit!; sleep 1
|
51
|
+
start_client!
|
52
|
+
|
53
|
+
# Server should have errors.
|
54
|
+
message_count = 0
|
55
|
+
lambda do
|
56
|
+
transport.after_receive_message = lambda do | t, message |
|
57
|
+
$stderr.write ">#{message_count += 1}" if verbose
|
58
|
+
if message_count >= 5
|
59
|
+
stop_client!
|
60
|
+
stop_conduit! :signal => 9
|
61
|
+
end
|
62
|
+
if message_count >= 10
|
63
|
+
t.stop!
|
64
|
+
end
|
65
|
+
end
|
66
|
+
start_server!
|
67
|
+
raise "start_server! exited"
|
68
|
+
end.should raise_error(Redis::CannotConnectError)
|
69
|
+
message_count.should == 5
|
70
|
+
exceptions.should == [ ]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
attr_accessor :transport, :target, :exceptions, :verbose
|
75
|
+
|
76
|
+
before :each do
|
77
|
+
@target = ASIR::Test::ResqueTarget.new
|
78
|
+
@exceptions = [ ]
|
79
|
+
@verbose = true
|
80
|
+
end
|
81
|
+
|
82
|
+
def with_cleanup!
|
83
|
+
yield
|
84
|
+
ensure
|
85
|
+
stop_client!
|
86
|
+
stop_server!
|
87
|
+
stop_conduit!
|
88
|
+
end
|
89
|
+
|
90
|
+
def create_transport!
|
91
|
+
@uri = "redis://localhost:23456"
|
92
|
+
@transport = ASIR::Transport::Resque.new(:uri => @uri)
|
93
|
+
transport.encoder = ASIR::Coder::Marshal.new
|
94
|
+
transport._logger = $stderr
|
95
|
+
transport._log_enabled = true
|
96
|
+
ASIR::Client::Proxy.config_callbacks[target.class] = lambda { | proxy |
|
97
|
+
proxy.transport = transport
|
98
|
+
}
|
99
|
+
end
|
100
|
+
|
101
|
+
def start_conduit!
|
102
|
+
transport.verbose = 0
|
103
|
+
transport.start_conduit!
|
104
|
+
transport.verbose = 0
|
105
|
+
end
|
106
|
+
|
107
|
+
def stop_conduit! opts = nil
|
108
|
+
transport.verbose = 0
|
109
|
+
transport.stop_conduit! opts
|
110
|
+
transport.verbose = 0
|
111
|
+
end
|
112
|
+
|
113
|
+
def start_client! &blk
|
114
|
+
@client_pid = Process.fork do
|
115
|
+
# transport.verbose = 3
|
116
|
+
i = 0
|
117
|
+
loop do
|
118
|
+
$stderr.write "<#{i += 1}" if verbose
|
119
|
+
target.asir.eval! "2 + 2"
|
120
|
+
sleep 0.25
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def stop_client!
|
126
|
+
if @client_pid
|
127
|
+
Process.kill 9, @client_pid
|
128
|
+
end
|
129
|
+
ensure
|
130
|
+
@client_pid = nil
|
131
|
+
end
|
132
|
+
|
133
|
+
def start_server!
|
134
|
+
transport.verbose = 0
|
135
|
+
transport.prepare_server!
|
136
|
+
transport.on_exception = lambda do | t, exc, kind, message, result |
|
137
|
+
@exceptions << exc
|
138
|
+
$stderr.puts " on_exception: #{kind.inspect}: #{exc.inspect}\n #{exc.backtrace * "\n "}"
|
139
|
+
end
|
140
|
+
transport.throttle = {
|
141
|
+
:min_sleep => 0.01,
|
142
|
+
:max_sleep => 2,
|
143
|
+
:inc_sleep => 0.1,
|
144
|
+
:mul_sleep => 1.25,
|
145
|
+
# :verbose => true,
|
146
|
+
}
|
147
|
+
transport.run_server!
|
148
|
+
transport.verbose = 0
|
149
|
+
end
|
150
|
+
|
151
|
+
def stop_server!
|
152
|
+
transport.stop!
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
module ASIR
|
157
|
+
module Test
|
158
|
+
class TestError < ::Exception; end
|
159
|
+
class ResqueTarget
|
160
|
+
include ASIR::Client
|
161
|
+
def raise_error! msg
|
162
|
+
raise TestError, msg
|
163
|
+
end
|
164
|
+
def eval! expr
|
165
|
+
result = eval expr
|
166
|
+
# $stderr.puts " #{self} eval!(#{expr.inspect}) => #{result.inspect}"
|
167
|
+
result
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
|
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.0.
|
4
|
+
version: 1.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,119 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
date: 2012-04-03 00:00:00.000000000 Z
|
13
|
-
dependencies:
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: uuid
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 2.3.5
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 2.3.5
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: redis
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 3.0.2
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 3.0.2
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: resque
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 1.23.0
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.23.0
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: httpclient
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 2.3.0
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 2.3.0
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: libxml-ruby
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 2.3.3
|
86
|
+
type: :runtime
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 2.3.3
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: rack
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 1.4.1
|
102
|
+
type: :runtime
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 1.4.1
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: zmq
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 2.1.4
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ~>
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: 2.1.4
|
14
126
|
description: Abstracting Services in Ruby
|
15
127
|
email: ks.ruby@kurtstephens.com
|
16
128
|
executables:
|
@@ -152,6 +264,7 @@ files:
|
|
152
264
|
- spec/json_spec.rb
|
153
265
|
- spec/message_spec.rb
|
154
266
|
- spec/performance_spec.rb
|
267
|
+
- spec/resque_spec.rb
|
155
268
|
- spec/spec_helper.rb
|
156
269
|
- spec/thread_variable_spec.rb
|
157
270
|
- spec/transport_spec.rb
|
@@ -190,6 +303,7 @@ test_files:
|
|
190
303
|
- spec/json_spec.rb
|
191
304
|
- spec/message_spec.rb
|
192
305
|
- spec/performance_spec.rb
|
306
|
+
- spec/resque_spec.rb
|
193
307
|
- spec/spec_helper.rb
|
194
308
|
- spec/thread_variable_spec.rb
|
195
309
|
- spec/transport_spec.rb
|