resque-aps 0.9.15 → 0.9.17
Sign up to get free protection for your applications and to get access to all the features.
- 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
|