em-resque 1.1.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,9 @@
1
+ THIS FORK
2
+ =========
3
+
4
+ This fork is intended to only run one fiber and does not use Fiber yielding to pick up jobs. This fork was created
5
+ because the EM::Synchrony.sleep solution does not work well for sending Apple Push Notifications.
6
+
1
7
  EM::Resque
2
8
  ==========
3
9
 
@@ -216,7 +222,7 @@ given a string or a Redis object. This means if you're already using
216
222
  Redis in your app, EM::Resquec an re-use the existing connection.
217
223
  EM::Resque is using the non-blocking em-redis when given the host as a
218
224
  string. If using a Redis object, please use the non-blocking
219
- EM::Protocols::Redis.
225
+ EM::Hiredis.
220
226
 
221
227
  String: `EM::Resque::WorkerMachine.new(opts.merge(:redis => 'localhost:6379'))`
222
228
 
@@ -1,28 +1,17 @@
1
1
  require 'resque'
2
2
  require 'em-synchrony'
3
- require 'em-synchrony/em-redis'
3
+ require 'em-hiredis'
4
4
  require 'em-synchrony/connection_pool'
5
5
  require 'uri'
6
6
 
7
7
  module EM::Resque
8
8
  extend Resque
9
9
 
10
- def self.initialize_redis(server, pool_size = 1)
10
+ def self.initialize_redis(server, namespace = :resque, pool_size = 1)
11
11
  case server
12
12
  when String
13
- opts = if server =~ /redis\:\/\//
14
- uri = URI.parse(server)
15
- {:host => uri.host, :port => uri.port}
16
- else
17
- server, namespace = server.split('/', 2)
18
- host, port, db = server.split(':')
19
- {:host => host, :port => port, :thread_safe => true, :db => db}
20
- end
21
-
22
- namespace ||= :resque
23
-
24
13
  redis = EventMachine::Synchrony::ConnectionPool.new(:size => pool_size) do
25
- EM::Protocols::Redis.connect(opts)
14
+ EM::Hiredis.connect(server)
26
15
  end
27
16
 
28
17
  Resque.redis = Redis::Namespace.new(namespace, :redis => redis)
@@ -1,5 +1,5 @@
1
1
  module EventMachine
2
2
  module Resque
3
- Version = VERSION = '1.1.0'
3
+ Version = VERSION = '1.1.1'
4
4
  end
5
5
  end
@@ -3,10 +3,83 @@ require 'resque'
3
3
  # A non-forking version of Resque worker, which handles waiting with
4
4
  # a non-blocking version of sleep.
5
5
  class EventMachine::Resque::Worker < Resque::Worker
6
+ attr_accessor :tick_instead_of_sleep
7
+
8
+ def initialize(*args)
9
+ super(*args)
10
+ self.tick_instead_of_sleep = false
11
+ end
12
+
6
13
  # Overwrite system sleep with the non-blocking version
7
14
  def sleep(interval)
8
15
  EM::Synchrony.sleep interval
9
16
  end
17
+
18
+ # Overwrite Resque's #work method to allow us to determine whether or not we want to ticks through a reactor
19
+ # instead of using EM::Synchrony sleep.
20
+ #
21
+ # The reason for this option is because when sending push notifications and using 1 fiber, the response from Apple
22
+ # will come after another job has been finished and is generally unreliable. Note that this means that you can't use
23
+ # this worker with more than one fiber for push workers.
24
+ def work(interval = 5.0, &block)
25
+ if self.tick_instead_of_sleep
26
+ work_tick(interval, &block)
27
+ else
28
+ super(interval, &block)
29
+ end
30
+ end
31
+
32
+ # Resque::Worker's #work method modified to use EM.next_tick instead of sleep
33
+ def work_tick(interval, &block)
34
+ interval = Float(interval)
35
+ $0 = "resque: Starting"
36
+ startup
37
+
38
+ work_loop = lambda do
39
+ if shutdown?
40
+ unregister_worker
41
+ EM.stop
42
+ next
43
+ end
44
+
45
+ if not paused? and job = reserve
46
+ log "got: #{job.inspect}"
47
+ job.worker = self
48
+ run_hook :before_fork, job
49
+ working_on job
50
+
51
+ if @child = fork
52
+ srand # Reseeding
53
+ procline "Forked #{@child} at #{Time.now.to_i}"
54
+ begin
55
+ Process.waitpid(@child)
56
+ rescue SystemCallError
57
+ nil
58
+ end
59
+ else
60
+ unregister_signal_handlers if !@cant_fork && term_child
61
+ procline "Processing #{job.queue} since #{Time.now.to_i}"
62
+ redis.client.reconnect # Don't share connection with parent
63
+ perform(job, &block)
64
+ exit! unless @cant_fork
65
+ EM::Timer.new(interval) do
66
+ EM.next_tick(&work_loop)
67
+ end
68
+ end
69
+
70
+ done_working
71
+ @child = nil
72
+ else
73
+ break if interval.zero?
74
+ log! "Sleeping for #{interval} seconds"
75
+ procline paused? ? "Paused" : "Waiting for #{@queues.join(',')}"
76
+ EM::Timer.new(interval) do
77
+ EM.next_tick(&work_loop)
78
+ end
79
+ end
80
+ end
81
+ EM.next_tick(&work_loop)
82
+ end
10
83
 
11
84
  # Be sure we're never forking
12
85
  def fork
@@ -16,24 +16,30 @@ module EventMachine
16
16
  # signals and prunes dead workers
17
17
  #
18
18
  # == Options
19
- # concurrency:: The number of green threads inside the machine (default 20)
19
+ # fibers:: The number of fibers to use in the worker (default 1)
20
20
  # interval:: Time in seconds how often the workers check for new work
21
21
  # (default 5)
22
- # fibers_count:: How many fibers (and workers) to be run inside the
23
- # machine (default 1)
24
22
  # queues:: Which queues to poll (default all)
25
23
  # verbose:: Verbose log output (default false)
26
24
  # vverbose:: Even more verbose log output (default false)
27
25
  # pidfile:: The file to save the process id number
26
+ # tick_instead_of_sleep:: Whether to tick through the reactor polling for jobs or use EM::Synchrony.sleep.
27
+ # Note that if you use this option, you'll be limited to 1 fiber.
28
28
  def initialize(opts = {})
29
- @concurrency = opts[:concurrency] || 20
30
29
  @interval = opts[:interval] || 5
31
30
  @fibers_count = opts[:fibers] || 1
32
31
  @queues = opts[:queue] || opts[:queues] || '*'
33
32
  @verbose = opts[:logging] || opts[:verbose] || false
34
33
  @very_verbose = opts[:vverbose] || false
35
34
  @pidfile = opts[:pidfile]
35
+ @redis_namespace = opts[:namespace] || :resque
36
36
  @redis_uri = opts[:redis] || "redis://127.0.0.1:6379"
37
+ @tick_instead_of_sleep = !opts[:tick_instead_of_sleep].nil? ? opts[:tick_instead_of_sleep] : false
38
+
39
+ # If we're ticking instead of sleeping, we can only have one fiber
40
+ if @tick_instead_of_sleep
41
+ @fibers_count = 1
42
+ end
37
43
 
38
44
  raise(ArgumentError, "Should have at least one fiber") if @fibers_count.to_i < 1
39
45
 
@@ -45,11 +51,15 @@ module EventMachine
45
51
  # Start the machine and start polling queues.
46
52
  def start
47
53
  EM.synchrony do
48
- EM::Resque.initialize_redis(@redis_uri, @fibers_count)
54
+ EM::Resque.initialize_redis(@redis_uri, @redis_namespace, @fibers_count)
49
55
  trap_signals
50
56
  prune_dead_workers
51
57
  @fibers.each(&:resume)
52
- system_monitor.resume
58
+
59
+ # If we're ticking and not sleeping, we don't need to monitor for yielding
60
+ unless @tick_instead_of_sleep
61
+ system_monitor.resume
62
+ end
53
63
  end
54
64
  end
55
65
 
@@ -76,6 +86,7 @@ module EventMachine
76
86
  worker = EM::Resque::Worker.new(*queues)
77
87
  worker.verbose = @verbose
78
88
  worker.very_verbose = @very_verbose
89
+ worker.tick_instead_of_sleep = @tick_instead_of_sleep
79
90
 
80
91
  worker
81
92
  end
@@ -12,10 +12,12 @@ context "Worker" do
12
12
  worker = EM::Resque::Worker.new('*')
13
13
  worker.work(0)
14
14
 
15
- assert_equal 1, EM::Resque.info[:processed]
15
+ EM::Timer.new(0.5) do
16
+ assert_equal 1, EM::Resque.info[:processed]
16
17
 
17
- worker.shutdown!
18
- EM.stop
18
+ worker.shutdown!
19
+ EM.stop
20
+ end
19
21
  end
20
22
  end
21
23
 
@@ -25,10 +27,12 @@ context "Worker" do
25
27
  worker = EM::Resque::Worker.new('*')
26
28
  worker.work(0)
27
29
 
28
- assert_equal 1, EM::Resque.redis.get("stat:processed_jobs").to_i
30
+ EM::Timer.new(0.5) do
31
+ assert_equal 1, EM::Resque.redis.get("stat:processed_jobs").to_i
29
32
 
30
- worker.shutdown!
31
- EM.stop
33
+ worker.shutdown!
34
+ EM.stop
35
+ end
32
36
  end
33
37
  end
34
38
 
@@ -38,9 +42,11 @@ context "Worker" do
38
42
  worker = EM::Resque::Worker.new('*')
39
43
  worker.work(0)
40
44
 
41
- assert_equal 1, Resque::Failure.count
42
- worker.shutdown!
43
- EM.stop
45
+ EM::Timer.new(0.5) do
46
+ assert_equal 1, Resque::Failure.count
47
+ worker.shutdown!
48
+ EM.stop
49
+ end
44
50
  end
45
51
  end
46
52
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: em-resque
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-23 00:00:00.000000000 Z
12
+ date: 2012-09-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: resque
@@ -44,13 +44,13 @@ dependencies:
44
44
  - !ruby/object:Gem::Version
45
45
  version: 1.0.0
46
46
  - !ruby/object:Gem::Dependency
47
- name: em-redis
47
+ name: em-hiredis
48
48
  requirement: !ruby/object:Gem::Requirement
49
49
  none: false
50
50
  requirements:
51
51
  - - ~>
52
52
  - !ruby/object:Gem::Version
53
- version: 0.3.0
53
+ version: 0.1.0
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
@@ -58,7 +58,7 @@ dependencies:
58
58
  requirements:
59
59
  - - ~>
60
60
  - !ruby/object:Gem::Version
61
- version: 0.3.0
61
+ version: 0.1.0
62
62
  description: ! " Em-resque is a version of Resque, which offers non-blocking and
63
63
  non-forking\n workers. The idea is to have fast as possible workers for tasks
64
64
  with lots of\n IO like pinging third party servers or hitting the database.\n\n
@@ -82,20 +82,20 @@ files:
82
82
  - Rakefile
83
83
  - LICENSE
84
84
  - HISTORY.md
85
- - lib/em-resque/version.rb
85
+ - lib/em-resque.rb
86
+ - lib/em-resque/task_helper.rb
86
87
  - lib/em-resque/worker.rb
87
- - lib/em-resque/tasks.rb
88
+ - lib/em-resque/version.rb
88
89
  - lib/em-resque/worker_machine.rb
89
- - lib/em-resque/task_helper.rb
90
+ - lib/em-resque/tasks.rb
90
91
  - lib/tasks/em-resque.rake
91
- - lib/em-resque.rb
92
92
  - test/worker_machine_test.rb
93
+ - test/redis-test-cluster.conf
93
94
  - test/em-resque_test.rb
94
- - test/redis-test.conf
95
95
  - test/task_helpers_test.rb
96
- - test/redis-test-cluster.conf
97
96
  - test/worker_test.rb
98
97
  - test/test_helper.rb
98
+ - test/redis-test.conf
99
99
  homepage: http://github.com/SponsorPay/em-resque
100
100
  licenses: []
101
101
  post_install_message: