resque-aps 0.9.15 → 0.9.17
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/HISTORY.md +16 -0
- data/README.markdown +1 -1
- data/lib/resque/plugins/aps/application.rb +88 -97
- data/lib/resque/plugins/{aps.rb → aps/aps.rb} +44 -4
- data/lib/resque/plugins/aps/daemon.rb +77 -0
- data/lib/resque/plugins/aps/notification.rb +3 -1
- data/lib/resque/plugins/aps/server.rb +15 -3
- data/lib/resque/plugins/aps/server/views/aps_applications.erb +27 -4
- data/lib/resque/plugins/aps/tasks.rb +11 -0
- data/lib/resque/plugins/aps/version.rb +1 -1
- data/lib/resque_aps.rb +1 -1
- data/test/test_helper.rb +4 -2
- metadata +8 -19
- data/.gitignore +0 -1
data/HISTORY.md
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
## 0.9.17 (2011-08-09)
|
2
|
+
|
3
|
+
* Add aps_retry flag to stop a daemon from looping back after the queue is empty
|
4
|
+
* Added daemon class to handle queuing applications. This should be scheduled to run every minute.
|
5
|
+
* Added new rake task to clear the APS application queued count.
|
6
|
+
* Changed the APS tab view for performance
|
7
|
+
* Added created_at attribute to Notification
|
8
|
+
*
|
9
|
+
|
10
|
+
## 0.9.16 (2011-06-02)
|
11
|
+
|
12
|
+
* Add previous notification to the failed_aps_write call
|
13
|
+
* Fixed aps_nil_notification_retry? call
|
14
|
+
* Fixed Application perform
|
15
|
+
* Improved web view
|
16
|
+
|
1
17
|
## 0.9.15 (2010-10-18)
|
2
18
|
|
3
19
|
* Move the application enqueue/dequeue methods to the Application class
|
data/README.markdown
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'openssl'
|
2
|
+
require 'benchmark'
|
2
3
|
|
3
4
|
module Resque
|
4
5
|
module Plugins
|
@@ -9,54 +10,91 @@ module Resque
|
|
9
10
|
|
10
11
|
attr_accessor :name, :cert_file, :cert_passwd
|
11
12
|
|
12
|
-
@queue
|
13
|
+
@queue = "apple_push_service"
|
14
|
+
@@CAFile = nil
|
13
15
|
|
14
16
|
def inspect
|
15
17
|
"#<#{self.class.name} #{name.inspect}, #{cert_passwd.inspect}, #{cert_file.inspect}>"
|
16
18
|
end
|
17
|
-
|
19
|
+
|
18
20
|
def self.perform(*args)
|
21
|
+
app_name = args[0]
|
22
|
+
@aps_retry = args[1] || false
|
23
|
+
begin
|
24
|
+
Resque.enqueue_aps_application(app_name) if @aps_retry
|
25
|
+
count, duration, ex = Resque::Plugins::Aps::Application.perform_no_fail(app_name)
|
26
|
+
logger.info("Sent #{count} #{app_name} notifications in batch over #{duration} sec.") if logger
|
27
|
+
Resque.dequeue_aps_application(app_name) if @aps_retry
|
28
|
+
raise ex if ex
|
29
|
+
rescue
|
30
|
+
Resque.dequeue_aps_application(app_name) if @aps_retry
|
31
|
+
raise $!
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.perform_clear(app_name)
|
36
|
+
while true
|
37
|
+
count, duration, ex = Resque::Plugins::Aps::Application.perform_no_fail(app_name, false, true)
|
38
|
+
p "Sent #{count} #{app_name} notifications in batch over #{duration} sec. Returned #{ex.inspect}"
|
39
|
+
break if ex.nil?
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.perform_no_fail(app_name, requeue = true, read_response = false)
|
19
44
|
count = 0
|
20
45
|
start = Time.now
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
46
|
+
excep = nil
|
47
|
+
duration = Benchmark.realtime do
|
48
|
+
Resque.aps_application(app_name).socket do |socket, app|
|
49
|
+
n_old = nil
|
50
|
+
while true
|
51
|
+
n = Resque.dequeue_aps(app_name)
|
52
|
+
if n.nil?
|
53
|
+
if @aps_retry && app.aps_nil_notification_retry?(count, start)
|
54
|
+
next
|
55
|
+
else
|
56
|
+
break
|
57
|
+
end
|
30
58
|
end
|
31
|
-
end
|
32
59
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
60
|
+
app.before_aps_write n
|
61
|
+
begin
|
62
|
+
n.batch_id = count + 1
|
63
|
+
n.expiry = Time.now.utc.to_i + 3600
|
64
|
+
socket.write(n.formatted)
|
65
|
+
app.after_aps_write n
|
66
|
+
count += 1
|
67
|
+
if read_response
|
68
|
+
resp = socket.read
|
69
|
+
if resp && resp != ""
|
70
|
+
# logger.error "Failure response: #{resp.inspect}" if logger
|
71
|
+
logger.error "Failure response: #{resp.bytes.to_a.map{|i| i.to_s(16)}.join}" if logger
|
72
|
+
break
|
73
|
+
end
|
74
|
+
end
|
75
|
+
rescue
|
76
|
+
# logger.error Application.application_exception($!, app_name) if logger
|
77
|
+
app.failed_aps_write n, $!, n_old
|
78
|
+
logger.error "#{$!}: Sent #{count} notifications before failure." if logger
|
79
|
+
Resque.enqueue_aps(app_name, n) if requeue
|
80
|
+
excep = $!
|
81
|
+
break
|
82
|
+
end
|
83
|
+
n_old = n
|
52
84
|
end
|
53
85
|
end
|
54
86
|
end
|
55
|
-
|
56
|
-
ensure
|
57
|
-
Resque.dequeue_aps_application(app_name)
|
87
|
+
return count, duration, excep
|
58
88
|
end
|
59
89
|
|
90
|
+
def self.verify_ssl_certificate(preverify_ok, ssl_context)
|
91
|
+
if preverify_ok != true || ssl_context.error != 0
|
92
|
+
err_msg = "SSL Verification failed -- Preverify: #{preverify_ok}, Error: #{ssl_context.error_string} (#{ssl_context.error})"
|
93
|
+
raise OpenSSL::SSL::SSLError.new(err_msg)
|
94
|
+
end
|
95
|
+
true
|
96
|
+
end
|
97
|
+
|
60
98
|
#
|
61
99
|
# Create the TCP and SSL sockets for sending the notification
|
62
100
|
#
|
@@ -65,6 +103,16 @@ module Resque
|
|
65
103
|
ctx.key = OpenSSL::PKey::RSA.new(cert, passphrase)
|
66
104
|
ctx.cert = OpenSSL::X509::Certificate.new(cert)
|
67
105
|
|
106
|
+
if @@CAFile && File.exists?(@@CAFile)
|
107
|
+
ctx.ca_file = @@CAFile
|
108
|
+
end
|
109
|
+
if defined?(ROOT_CA) && ROOT_CA && File.directory?(ROOT_CA)
|
110
|
+
ctx.ca_path = ROOT_CA
|
111
|
+
end
|
112
|
+
ctx.verify_callback = proc do |preverify_ok, ssl_context|
|
113
|
+
Resque::Plugins::Aps::Application.verify_ssl_certificate(preverify_ok, ssl_context)
|
114
|
+
end
|
115
|
+
|
68
116
|
s = TCPSocket.new(host, port)
|
69
117
|
ssl = OpenSSL::SSL::SSLSocket.new(s, ctx)
|
70
118
|
ssl.sync = true
|
@@ -98,13 +146,13 @@ module Resque
|
|
98
146
|
exc.set_backtrace(exception.backtrace)
|
99
147
|
return exc
|
100
148
|
end
|
101
|
-
|
149
|
+
|
102
150
|
def initialize(attributes)
|
103
151
|
attributes.each do |k, v|
|
104
152
|
respond_to?(:"#{k}=") ? send(:"#{k}=", v) : raise(Resque::Plugins::Aps::UnknownAttributeError, "unknown attribute: #{k}")
|
105
153
|
end
|
106
154
|
end
|
107
|
-
|
155
|
+
|
108
156
|
def socket(cert = nil, certp = nil, host = nil, port = nil, &block)
|
109
157
|
logger.debug("resque-aps: ssl_socket(#{name})") if logger
|
110
158
|
exc = nil
|
@@ -117,13 +165,13 @@ module Resque
|
|
117
165
|
rescue
|
118
166
|
raise Application.application_exception($!, name)
|
119
167
|
end
|
120
|
-
|
168
|
+
|
121
169
|
begin
|
122
170
|
ssl_socket.connect
|
123
171
|
yield ssl_socket, self if block_given?
|
124
172
|
rescue
|
125
173
|
exc = Application.application_exception($!, name)
|
126
|
-
if $!.message =~ /^SSL_connect .* certificate (expired|revoked)/
|
174
|
+
if $!.message =~ /^SSL_connect .* certificate (expired|revoked)/ || $!.message =~ /^SSL Verification failed/
|
127
175
|
notify_aps_admin exc
|
128
176
|
end
|
129
177
|
raise exc
|
@@ -137,7 +185,7 @@ module Resque
|
|
137
185
|
def to_hash
|
138
186
|
{'name' => name, 'cert_file' => cert_file, 'cert_passwd' => cert_passwd}
|
139
187
|
end
|
140
|
-
|
188
|
+
|
141
189
|
def to_json
|
142
190
|
to_hash.to_json
|
143
191
|
end
|
@@ -150,7 +198,7 @@ module Resque
|
|
150
198
|
logger.debug("ResqueAps[after_write]: #{notification}") if logger
|
151
199
|
end
|
152
200
|
|
153
|
-
def failed_aps_write(notification, exception)
|
201
|
+
def failed_aps_write(notification, exception, previous_notification = nil)
|
154
202
|
logger.error("ResqueAps[write_failed]: #{exception} (#{notification}): #{exception.backtrace.join("\n")}") if logger
|
155
203
|
end
|
156
204
|
|
@@ -177,63 +225,6 @@ module Resque
|
|
177
225
|
logger.error("ResqueAps[read_failed]: Bad data on the socket (#{name})") if logger
|
178
226
|
end
|
179
227
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
def queued_count
|
185
|
-
(redis.get(Resque.aps_application_queued_key(name)) || 0).to_i
|
186
|
-
end
|
187
|
-
|
188
|
-
def lock_key
|
189
|
-
@lock_key ||= "#{Resque.aps_application_key(name)}:lock"
|
190
|
-
end
|
191
|
-
|
192
|
-
def redis
|
193
|
-
Resque.redis
|
194
|
-
end
|
195
|
-
|
196
|
-
def acquire_lock
|
197
|
-
if redis.setnx(lock_key, Time.now.utc.to_i + 1)
|
198
|
-
true
|
199
|
-
elsif Time.at(redis.get(lock_key).to_i) > Time.now
|
200
|
-
delete_lock
|
201
|
-
acquire_lock
|
202
|
-
else
|
203
|
-
false
|
204
|
-
end
|
205
|
-
end
|
206
|
-
|
207
|
-
def delete_lock
|
208
|
-
redis.del(lock_key)
|
209
|
-
end
|
210
|
-
|
211
|
-
def enqueue(override = false)
|
212
|
-
count_apps = 0
|
213
|
-
count_not = 0
|
214
|
-
locked = false
|
215
|
-
|
216
|
-
unless override
|
217
|
-
count_apps = queued_count
|
218
|
-
if count_apps == 0
|
219
|
-
locked = acquire_lock
|
220
|
-
return unless locked
|
221
|
-
count_apps = queued_count
|
222
|
-
end
|
223
|
-
count_not = Resque.aps_notification_count_for_application(name)
|
224
|
-
end
|
225
|
-
|
226
|
-
if count_apps <= 0 || (count_apps < Resque.aps_application_job_limit && (count_not > Resque.aps_queue_size_upper && count_not % (Resque.aps_queue_size_upper / 10) == 0))
|
227
|
-
enqueue(Resque::Plugins::Aps::Application, name)
|
228
|
-
redis.incr(Resque.aps_application_queued_key(name))
|
229
|
-
delete_lock if locked
|
230
|
-
end
|
231
|
-
end
|
232
|
-
|
233
|
-
def dequeue
|
234
|
-
redis.decr(Resque.aps_application_queued_key(name))
|
235
|
-
end
|
236
|
-
|
237
228
|
end
|
238
229
|
end
|
239
230
|
end
|
@@ -61,18 +61,48 @@ module Resque
|
|
61
61
|
def aps_application_job_limit
|
62
62
|
@aps_application_job_limit ||= 5
|
63
63
|
end
|
64
|
-
|
64
|
+
|
65
|
+
def aps_applications_queued_count(application_name)
|
66
|
+
(redis.get(Resque.aps_application_queued_key(name)) || 0).to_i
|
67
|
+
end
|
68
|
+
|
69
|
+
# Increase the count of queued application workers
|
70
|
+
def enqueue_aps_application(application_name, override = false)
|
71
|
+
res = redis.incr(aps_application_queued_key(application_name))
|
72
|
+
end
|
73
|
+
|
74
|
+
# Decrease the count of queued application workers
|
75
|
+
def dequeue_aps_application(application_name)
|
76
|
+
res = redis.decr(aps_application_queued_key(application_name))
|
77
|
+
end
|
78
|
+
|
79
|
+
# Push the given notification onto the given application queue
|
80
|
+
# returns true
|
65
81
|
def enqueue_aps(application_name, notification)
|
82
|
+
create_aps_application(application_name, nil, nil) unless aps_application_exists?(application_name)
|
66
83
|
redis.rpush(aps_application_queue_key(application_name), encode(notification.to_hash))
|
67
|
-
|
84
|
+
if inline?
|
85
|
+
Resque::Plugins::Aps::Application.perform(application_name, false)
|
86
|
+
end
|
68
87
|
true
|
69
88
|
end
|
70
89
|
|
90
|
+
# Pop the oldest notification off the given application queue
|
91
|
+
# returns nil - if there are none on the queue
|
71
92
|
def dequeue_aps(application_name)
|
72
93
|
h = decode(redis.lpop(aps_application_queue_key(application_name)))
|
73
94
|
h ? Resque::Plugins::Aps::Notification.new(h) : nil
|
74
95
|
end
|
75
|
-
|
96
|
+
|
97
|
+
|
98
|
+
# Age of the oldest notification in the given application queue, in seconds
|
99
|
+
# returns 0 - if there are no notifications on the queue or the oldest has no create time
|
100
|
+
def aps_age(application_name)
|
101
|
+
h = decode(redis.lindex(aps_application_queue_key(application_name), 0))
|
102
|
+
res = h ? h['created_at'] ? Time.now.utc - Time.parse(h['created_at']) : 0 : 0
|
103
|
+
return res
|
104
|
+
end
|
105
|
+
|
76
106
|
# Returns the number of queued notifications for a given application
|
77
107
|
def aps_notification_count_for_application(application_name)
|
78
108
|
redis.llen(aps_application_queue_key(application_name)).to_i
|
@@ -88,7 +118,17 @@ module Resque
|
|
88
118
|
redis.set(aps_application_key(name), encode({'name' => name, 'cert_file' => cert_file, 'cert_passwd' => cert_passwd}))
|
89
119
|
redis.sadd(:aps_applications, name)
|
90
120
|
end
|
91
|
-
|
121
|
+
|
122
|
+
def delete_aps_application(name)
|
123
|
+
redis.del(aps_application_key(name))
|
124
|
+
redis.srem(:aps_applications, name)
|
125
|
+
redis.del(aps_application_queue_key(name))
|
126
|
+
end
|
127
|
+
|
128
|
+
def aps_application_exists?(name)
|
129
|
+
redis.exists(aps_application_key(name)) == 1
|
130
|
+
end
|
131
|
+
|
92
132
|
def aps_application(name)
|
93
133
|
h = decode(redis.get(aps_application_key(name)))
|
94
134
|
h ? Resque::Plugins::Aps::Application.new(h) : nil
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module Resque
|
4
|
+
module Plugins
|
5
|
+
module Aps
|
6
|
+
class Daemon
|
7
|
+
include Resque::Plugins::Aps::Helper
|
8
|
+
extend Resque::Plugins::Aps::Helper
|
9
|
+
|
10
|
+
class << self
|
11
|
+
|
12
|
+
# Schedule all jobs and continually look for delayed jobs (never returns)
|
13
|
+
def run
|
14
|
+
# trap signals
|
15
|
+
register_signal_handlers
|
16
|
+
|
17
|
+
# Now start the scheduling part of the loop.
|
18
|
+
loop do
|
19
|
+
handle_aps_queues(30)
|
20
|
+
poll_sleep
|
21
|
+
end
|
22
|
+
|
23
|
+
# never gets here.
|
24
|
+
rescue
|
25
|
+
logger.error "#{$!}: #{$!.backtrace.join("\n")}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def handle_aps_queues(max_age = 60)
|
29
|
+
Resque.aps_application_names(0, 0).each do |app_name|
|
30
|
+
count_not = Resque.aps_notification_count_for_application(app_name)
|
31
|
+
if count_not > 0
|
32
|
+
count_apps = Resque.aps_applications_queued_count(app_name).to_i
|
33
|
+
if count_apps == 0
|
34
|
+
Resque.enqueue(Resque::Plugins::Aps::Application, app_name, true)
|
35
|
+
elsif Resque.aps_age(app_name) >= max_age
|
36
|
+
Resque.enqueue(Resque::Plugins::Aps::Application, app_name, false)
|
37
|
+
else
|
38
|
+
logger.error "Unable to queue APS application: #{app_name}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# For all signals, set the shutdown flag and wait for current
|
45
|
+
# poll/enqueing to finish (should be almost istant). In the
|
46
|
+
# case of sleeping, exit immediately.
|
47
|
+
def register_signal_handlers
|
48
|
+
trap("TERM") { shutdown }
|
49
|
+
trap("INT") { shutdown }
|
50
|
+
trap('QUIT') { shutdown } unless defined? JRUBY_VERSION
|
51
|
+
end
|
52
|
+
|
53
|
+
def handle_shutdown
|
54
|
+
exit if @shutdown
|
55
|
+
yield
|
56
|
+
exit if @shutdown
|
57
|
+
end
|
58
|
+
|
59
|
+
# Sleeps and returns true
|
60
|
+
def poll_sleep
|
61
|
+
@sleeping = true
|
62
|
+
handle_shutdown { sleep 5 }
|
63
|
+
@sleeping = false
|
64
|
+
true
|
65
|
+
end
|
66
|
+
|
67
|
+
# Sets the shutdown flag, exits if sleeping
|
68
|
+
def shutdown
|
69
|
+
@shutdown = true
|
70
|
+
exit if @sleeping
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -5,12 +5,14 @@ module Resque
|
|
5
5
|
include Resque::Plugins::Aps::Helper
|
6
6
|
extend Resque::Plugins::Aps::Helper
|
7
7
|
|
8
|
-
attr_accessor :application_name, :device_token, :payload, :batch_id, :expiry
|
8
|
+
attr_accessor :application_name, :device_token, :payload, :batch_id, :expiry, :created_at
|
9
9
|
|
10
10
|
def initialize(attributes)
|
11
11
|
attributes.each do |k, v|
|
12
12
|
respond_to?(:"#{k}=") ? send(:"#{k}=", v) : raise(Resque::Plugins::Aps::UnknownAttributeError, "unknown attribute: #{k}")
|
13
13
|
end
|
14
|
+
@created_at = Time.now.utc unless @created_at
|
15
|
+
@created_at = Time.parse(@created_at) if @created_at.kind_of?(String)
|
14
16
|
end
|
15
17
|
|
16
18
|
def inspect
|
@@ -10,19 +10,31 @@ module Resque
|
|
10
10
|
|
11
11
|
base.class_eval do
|
12
12
|
|
13
|
+
aps_dir = File.dirname(File.expand_path(__FILE__)) + "/server/views"
|
14
|
+
|
13
15
|
get "/aps" do
|
14
16
|
# Is there a better way to specify alternate template locations with sinatra?
|
15
|
-
erb File.read(
|
17
|
+
erb File.read("#{aps_dir}/aps_applications.erb"), :resque => Resque
|
16
18
|
end
|
17
19
|
|
18
20
|
get "/aps/:application_name" do
|
19
21
|
# Is there a better way to specify alternate template locations with sinatra?
|
20
|
-
erb File.read(
|
22
|
+
erb File.read("#{aps_dir}/notifications.erb"), :resque => Resque
|
21
23
|
end
|
22
24
|
|
23
25
|
post "/aps/:application_name" do
|
24
26
|
Resque.enqueue(Resque::Plugins::Aps::Application, params[:application_name])
|
25
|
-
redirect url("/aps")
|
27
|
+
redirect url("/aps?page_size=0")
|
28
|
+
end
|
29
|
+
|
30
|
+
post "/aps/:application_name/reset" do
|
31
|
+
Resque.redis.set(Resque.aps_application_queued_key(params[:application_name]), 0)
|
32
|
+
redirect url("/aps?page_size=0")
|
33
|
+
end
|
34
|
+
|
35
|
+
post "/aps/:application_name/delete" do
|
36
|
+
Resque.delete_aps_application(params[:application_name])
|
37
|
+
redirect url("/aps?page_size=0")
|
26
38
|
end
|
27
39
|
end
|
28
40
|
|
@@ -5,26 +5,49 @@
|
|
5
5
|
</p>
|
6
6
|
|
7
7
|
<p class='sub'>
|
8
|
-
Showing
|
8
|
+
Showing <b><%=size = Resque.aps_applications_count %></b> applications.
|
9
9
|
</p>
|
10
10
|
|
11
11
|
<table>
|
12
12
|
<tr>
|
13
13
|
<th>Application</th>
|
14
14
|
<th>Notification Count</th>
|
15
|
+
<th>Queued Count</th>
|
15
16
|
<th></th>
|
16
17
|
</tr>
|
17
|
-
<%
|
18
|
+
<%
|
19
|
+
application_names = Resque.aps_application_names(0, 0)
|
20
|
+
application_data = {}
|
21
|
+
application_names.each do |app_name|
|
22
|
+
application_data[app_name] = [
|
23
|
+
Resque.aps_notification_count_for_application(app_name),
|
24
|
+
Resque.aps_applications_queued_count(app_name).to_i
|
25
|
+
]
|
26
|
+
end
|
27
|
+
application_names.sort! { |x,y|
|
28
|
+
ret = application_data[y][0] <=> application_data[x][0]
|
29
|
+
ret = application_data[y][1] <=> application_data[x][1] if ret == 0
|
30
|
+
ret = x <=> y if ret == 0
|
31
|
+
ret
|
32
|
+
}
|
33
|
+
%>
|
34
|
+
<% application_names.each do |application_name| %>
|
18
35
|
<tr>
|
19
36
|
<td><a href="<%= url "aps/#{application_name}" %>"><%= application_name %></a></td>
|
20
|
-
<td><%=
|
37
|
+
<td><%= application_data[application_name][0] %></td>
|
38
|
+
<td><%= application_data[application_name][1] %></td>
|
21
39
|
<td>
|
22
40
|
<form action="<%= url "/aps/#{application_name}" %>" method="post">
|
23
41
|
<input type="submit" value="Queue worker">
|
24
42
|
</form>
|
43
|
+
<form action="<%= url "/aps/#{application_name}/reset" %>" method="post">
|
44
|
+
<input type="submit" value="Reset queued count">
|
45
|
+
</form>
|
46
|
+
<form action="<%= url "/aps/#{application_name}/delete" %>" method="post">
|
47
|
+
<input type="submit" value="Remove queue">
|
48
|
+
</form>
|
25
49
|
</td>
|
26
50
|
</tr>
|
27
51
|
<% end %>
|
28
52
|
</table>
|
29
53
|
|
30
|
-
<%= partial :next_more, :start => start, :size => size %>
|
@@ -19,6 +19,17 @@ namespace :resque do
|
|
19
19
|
abort "None"
|
20
20
|
end
|
21
21
|
end
|
22
|
+
|
23
|
+
desc "Reset the queued worker counts"
|
24
|
+
task :reset_queue_workers => :setup do
|
25
|
+
require 'resque'
|
26
|
+
require 'resque_aps'
|
27
|
+
|
28
|
+
application_names = Resque.aps_application_names(0, 0)
|
29
|
+
application_names.each do |application_name|
|
30
|
+
Resque.redis.set(Resque.aps_application_queued_key(application_name), 0)
|
31
|
+
end
|
32
|
+
end
|
22
33
|
end
|
23
34
|
|
24
35
|
end
|
data/lib/resque_aps.rb
CHANGED
data/test/test_helper.rb
CHANGED
@@ -3,15 +3,17 @@
|
|
3
3
|
# to do all the same stuff
|
4
4
|
|
5
5
|
dir = File.dirname(File.expand_path(__FILE__))
|
6
|
+
$LOAD_PATH.unshift dir + '/../lib'
|
7
|
+
$: << (File.dirname(__FILE__) + '/../lib')
|
6
8
|
|
7
9
|
require 'rubygems'
|
8
10
|
require 'test/unit'
|
9
11
|
require 'mocha'
|
10
12
|
require 'resque'
|
11
13
|
require 'ruby-debug'
|
12
|
-
require
|
13
|
-
$LOAD_PATH.unshift File.dirname(File.expand_path(__FILE__)) + '/../lib'
|
14
|
+
require 'resque_aps'
|
14
15
|
|
16
|
+
ROOT_CA = '/etc/ssl/certs'
|
15
17
|
|
16
18
|
#
|
17
19
|
# make sure we can run redis
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: resque-aps
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 37
|
5
4
|
prerelease: false
|
6
5
|
segments:
|
7
6
|
- 0
|
8
7
|
- 9
|
9
|
-
-
|
10
|
-
version: 0.9.
|
8
|
+
- 17
|
9
|
+
version: 0.9.17
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Ashley Martens
|
@@ -15,18 +14,16 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date:
|
17
|
+
date: 2011-08-09 00:00:00 -07:00
|
19
18
|
default_executable:
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
22
21
|
name: jeweler
|
23
22
|
prerelease: false
|
24
23
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
24
|
requirements:
|
27
25
|
- - ">="
|
28
26
|
- !ruby/object:Gem::Version
|
29
|
-
hash: 3
|
30
27
|
segments:
|
31
28
|
- 0
|
32
29
|
version: "0"
|
@@ -36,11 +33,9 @@ dependencies:
|
|
36
33
|
name: mocha
|
37
34
|
prerelease: false
|
38
35
|
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
-
none: false
|
40
36
|
requirements:
|
41
37
|
- - ">="
|
42
38
|
- !ruby/object:Gem::Version
|
43
|
-
hash: 3
|
44
39
|
segments:
|
45
40
|
- 0
|
46
41
|
version: "0"
|
@@ -50,11 +45,9 @@ dependencies:
|
|
50
45
|
name: rack-test
|
51
46
|
prerelease: false
|
52
47
|
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
-
none: false
|
54
48
|
requirements:
|
55
49
|
- - ">="
|
56
50
|
- !ruby/object:Gem::Version
|
57
|
-
hash: 3
|
58
51
|
segments:
|
59
52
|
- 0
|
60
53
|
version: "0"
|
@@ -73,13 +66,13 @@ extra_rdoc_files:
|
|
73
66
|
- LICENSE
|
74
67
|
- README.markdown
|
75
68
|
files:
|
76
|
-
- .gitignore
|
77
69
|
- HISTORY.md
|
78
70
|
- LICENSE
|
79
71
|
- README.markdown
|
80
72
|
- Rakefile
|
81
|
-
- lib/resque/plugins/aps.rb
|
82
73
|
- lib/resque/plugins/aps/application.rb
|
74
|
+
- lib/resque/plugins/aps/aps.rb
|
75
|
+
- lib/resque/plugins/aps/daemon.rb
|
83
76
|
- lib/resque/plugins/aps/feedback.rb
|
84
77
|
- lib/resque/plugins/aps/helper.rb
|
85
78
|
- lib/resque/plugins/aps/notification.rb
|
@@ -104,32 +97,28 @@ homepage: http://github.com/ashleym1972/resque-aps
|
|
104
97
|
licenses: []
|
105
98
|
|
106
99
|
post_install_message:
|
107
|
-
rdoc_options:
|
108
|
-
|
100
|
+
rdoc_options: []
|
101
|
+
|
109
102
|
require_paths:
|
110
103
|
- lib
|
111
104
|
required_ruby_version: !ruby/object:Gem::Requirement
|
112
|
-
none: false
|
113
105
|
requirements:
|
114
106
|
- - ">="
|
115
107
|
- !ruby/object:Gem::Version
|
116
|
-
hash: 3
|
117
108
|
segments:
|
118
109
|
- 0
|
119
110
|
version: "0"
|
120
111
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
|
-
none: false
|
122
112
|
requirements:
|
123
113
|
- - ">="
|
124
114
|
- !ruby/object:Gem::Version
|
125
|
-
hash: 3
|
126
115
|
segments:
|
127
116
|
- 0
|
128
117
|
version: "0"
|
129
118
|
requirements: []
|
130
119
|
|
131
120
|
rubyforge_project:
|
132
|
-
rubygems_version: 1.3.
|
121
|
+
rubygems_version: 1.3.6
|
133
122
|
signing_key:
|
134
123
|
specification_version: 3
|
135
124
|
summary: Queuing system for Apple's Push Service on top of Resque
|
data/.gitignore
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
*.pem
|