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 CHANGED
@@ -1 +1 @@
1
- 1.0.1
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.1"
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 ||= [ ::SystemExit, ::Interrupt, ::SignalException ]
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
@@ -34,6 +34,12 @@ module ASIR
34
34
  def invoke!
35
35
  raise resolve_object(@exception_class), @exception_message, @exception_backtrace
36
36
  end
37
+
38
+ def construct!
39
+ invoke!
40
+ rescue ::Exception => exc
41
+ exc
42
+ end
37
43
  end
38
44
  # !SLIDE END
39
45
  end
@@ -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
- begin
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
@@ -60,6 +60,7 @@ module ASIR
60
60
  _log { [ :_receive_message, :exception, exc ] }
61
61
  additional_data[:beanstalk_error] = exc
62
62
  channel.close
63
+ raise exc
63
64
  end
64
65
  end
65
66
  end
@@ -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
- $! = first_exception
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
- ::Process.kill 'TERM', @conduit_pid
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
@@ -21,8 +21,7 @@ module ASIR
21
21
  end
22
22
  unless sent
23
23
  if first_exception && @reraise_first_exception
24
- $! = first_exception
25
- raise
24
+ raise first_exception
26
25
  end
27
26
  raise FallbackError, "fallback failed"
28
27
  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
- # $stderr.puts " #{self} resque_worker = #{resque_worker} on queues #{resque_worker.queues}"
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
  #########################################
@@ -24,7 +24,8 @@ module ASIR
24
24
  @running = false
25
25
  _log [ :serve_stream_terminate, err ]
26
26
  rescue ::Exception => err
27
- _log [ :serve_stream_error, err ]
27
+ _log [ :serve_stream_error, err, err.backtrace ]
28
+ raise err
28
29
  end
29
30
  end
30
31
  end
data/lib/asir/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module ASIR
2
- VERSION = "1.0.1"
2
+ VERSION = "1.0.4"
3
3
  end
@@ -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.1
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