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.
- data/README.markdown +7 -1
- data/lib/em-resque.rb +3 -14
- data/lib/em-resque/version.rb +1 -1
- data/lib/em-resque/worker.rb +73 -0
- data/lib/em-resque/worker_machine.rb +17 -6
- data/test/worker_test.rb +15 -9
- metadata +11 -11
data/README.markdown
CHANGED
@@ -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::
|
225
|
+
EM::Hiredis.
|
220
226
|
|
221
227
|
String: `EM::Resque::WorkerMachine.new(opts.merge(:redis => 'localhost:6379'))`
|
222
228
|
|
data/lib/em-resque.rb
CHANGED
@@ -1,28 +1,17 @@
|
|
1
1
|
require 'resque'
|
2
2
|
require 'em-synchrony'
|
3
|
-
require 'em-
|
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::
|
14
|
+
EM::Hiredis.connect(server)
|
26
15
|
end
|
27
16
|
|
28
17
|
Resque.redis = Redis::Namespace.new(namespace, :redis => redis)
|
data/lib/em-resque/version.rb
CHANGED
data/lib/em-resque/worker.rb
CHANGED
@@ -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
|
-
#
|
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
|
-
|
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
|
data/test/worker_test.rb
CHANGED
@@ -12,10 +12,12 @@ context "Worker" do
|
|
12
12
|
worker = EM::Resque::Worker.new('*')
|
13
13
|
worker.work(0)
|
14
14
|
|
15
|
-
|
15
|
+
EM::Timer.new(0.5) do
|
16
|
+
assert_equal 1, EM::Resque.info[:processed]
|
16
17
|
|
17
|
-
|
18
|
-
|
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
|
-
|
30
|
+
EM::Timer.new(0.5) do
|
31
|
+
assert_equal 1, EM::Resque.redis.get("stat:processed_jobs").to_i
|
29
32
|
|
30
|
-
|
31
|
-
|
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
|
-
|
42
|
-
|
43
|
-
|
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.
|
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-
|
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-
|
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.
|
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.
|
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
|
85
|
+
- lib/em-resque.rb
|
86
|
+
- lib/em-resque/task_helper.rb
|
86
87
|
- lib/em-resque/worker.rb
|
87
|
-
- lib/em-resque/
|
88
|
+
- lib/em-resque/version.rb
|
88
89
|
- lib/em-resque/worker_machine.rb
|
89
|
-
- lib/em-resque/
|
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:
|