em-resque 1.1.0 → 1.1.1

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.
@@ -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: