juggler 0.0.1 → 0.0.2

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
- 0.0.1
1
+ 0.0.2
data/examples/app.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'sinatra'
3
+
4
+ get '/slow' do
5
+ sleep 3
6
+ return 'Finally done'
7
+ end
@@ -1,12 +1,15 @@
1
1
  require 'rubygems'
2
2
  $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
3
  require 'juggler'
4
+ require 'eventmachine'
5
+
6
+ Juggler.logger = Logger.new(STDOUT)
4
7
 
5
8
  EM.run {
6
9
  Juggler.juggle(:http, 3) do |path|
7
10
  http = EM::Protocols::HttpClient.request({
8
- :host => "0.0.0.0",
9
- :port => 3000,
11
+ :host => "localhost",
12
+ :port => 4567,
10
13
  :request => path
11
14
  })
12
15
  http.callback do |response|
@@ -2,10 +2,19 @@ require 'rubygems'
2
2
  $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
3
  require 'juggler'
4
4
 
5
+ Juggler.logger = Logger.new(STDOUT)
6
+
5
7
  # Throw some jobs
6
8
 
7
- 10.times do |i|
9
+ class Foo; end
10
+
11
+ 2.times do |i|
8
12
  path = ['/fast', '/slow'][i % 2]
9
- Juggler.throw(:http, path)
13
+ Juggler.throw(:http, path, {
14
+ :ttr => 1
15
+ })
10
16
  end
11
17
  10.times { Juggler.throw(:timer, {:foo => 'bar'}) }
18
+
19
+ # Test that unmarshaling errors are handled
20
+ Juggler.throw(:http, Foo.new)
data/lib/juggler.rb CHANGED
@@ -22,7 +22,13 @@ class Juggler
22
22
  def throw(method, params, options = {})
23
23
  # TODO: Do some checking on the method
24
24
  connection.use(method.to_s)
25
- connection.put(Marshal.dump(params))
25
+
26
+ priority = options[:priority] || 50
27
+ delay = 0
28
+ # Add 2s because we want to handle the timeout before beanstalk does
29
+ ttr = (options[:ttr] || 60) + 2
30
+
31
+ connection.put(Marshal.dump(params), priority, delay, ttr)
26
32
  end
27
33
 
28
34
  def juggle(method, concurrency = 1, &strategy)
@@ -19,19 +19,46 @@ class Juggler
19
19
 
20
20
  def reserve
21
21
  beanstalk_job = connection.reserve(0)
22
- params = Marshal.load(beanstalk_job.body)
23
- job = @strategy.call(params)
22
+
23
+ begin
24
+ params = Marshal.load(beanstalk_job.body)
25
+ rescue => e
26
+ handle_exception(e, "Exception unmarshaling #{@queue} job")
27
+ beanstalk_job.delete
28
+ return
29
+ end
30
+
31
+ begin
32
+ job = @strategy.call(params)
33
+ rescue => e
34
+ handle_exception(e, "Exception calling #{@queue} strategy")
35
+ beanstalk_job.decay
36
+ return
37
+ end
38
+
39
+ EM::Timer.new(beanstalk_job.ttr - 2) do
40
+ job.fail(:timeout)
41
+ end
42
+
24
43
  @running << job
25
44
  job.callback do
26
45
  @running.delete(job)
27
46
  beanstalk_job.delete
28
47
  end
29
- job.errback do
48
+ job.errback do |error|
49
+ Juggler.logger.info("#{@queue} job failed: #{error}")
30
50
  @running.delete(job)
31
51
  # Built in exponential backoff
32
52
  beanstalk_job.decay
33
53
  end
34
54
  rescue Beanstalk::TimedOut
55
+ rescue Beanstalk::NotConnected
56
+ Juggler.logger.fatal "Could not connect any beanstalk hosts. " \
57
+ "Retrying in 1s."
58
+ sleep 1
59
+ rescue => e
60
+ handle_exception(e, "Unhandled exception")
61
+ beanstalk_job.delete if beanstalk_job
35
62
  end
36
63
 
37
64
  def run
@@ -47,6 +74,11 @@ class Juggler
47
74
  @running.size < @concurrency
48
75
  end
49
76
 
77
+ def handle_exception(e, message)
78
+ Juggler.logger.error "#{message}: #{e.class} #{e.message}"
79
+ Juggler.logger.debug e.backtrace.join("\n")
80
+ end
81
+
50
82
  def connection
51
83
  @pool ||= begin
52
84
  pool = Beanstalk::Pool.new(Juggler.hosts)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: juggler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martyn Loughran
@@ -66,5 +66,6 @@ test_files:
66
66
  - spec/juggler_spec.rb
67
67
  - spec/runner_spec.rb
68
68
  - spec/spec_helper.rb
69
+ - examples/app.rb
69
70
  - examples/test_consumer.rb
70
71
  - examples/test_producer.rb