asir 1.0.1 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
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