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 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
@@ -13,7 +13,7 @@ To install:
13
13
 
14
14
  You'll need to add this to your Rails rakefile to see the queue lengths:
15
15
 
16
- require 'resque_aps/tasks'
16
+ require 'resque/plugins/aps/tasks'
17
17
  task "resque:setup" => :environment
18
18
 
19
19
  $ rake resque:aps:queue_lengths
@@ -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 = "apple_push_service"
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
- app_name = args[0]
22
- Resque.aps_application(app_name).socket do |socket, app|
23
- while true
24
- n = Resque.dequeue_aps(app_name)
25
- if n.nil?
26
- if app.aps_nil_notification_retry? count, start
27
- next
28
- else
29
- break
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
- app.before_aps_write n
34
- begin
35
- n.batch_id = count + 1
36
- n.expiry = Time.now.utc.to_i + 3600
37
- socket.write(n.formatted)
38
- app.after_aps_write n
39
- count += 1
40
- # resp = socket.read
41
- # if resp && resp != ""
42
- # # logger.error "Failure response: #{resp.inspect}" if logger
43
- # logger.error "Failure response: #{resp.bytes.to_a.map{|i| i.to_s(16)}.join}" if logger
44
- # break
45
- # end
46
- rescue
47
- logger.error Application.application_exception($!, app_name) if logger
48
- app.failed_aps_write n, $!
49
- logger.error "#{$!}: Sent #{count} notifications before failure." if logger
50
- Resque.enqueue_aps(app_name, n)
51
- break
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
- logger.info("Sent #{count} #{app_name} notifications in batch over #{Time.now - start} sec.") if logger
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
- Resque::Plugins::Aps::Application.new('name' => application_name).enqueue
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(File.join(File.dirname(__FILE__), 'server/views/aps_applications.erb'))
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(File.join(File.dirname(__FILE__), 'server/views/notifications.erb'))
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 <%= start = params[:start].to_i %> to <%= start + 20 %> of <b><%=size = resque.aps_applications_count %></b> applications.
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
- <% resque.aps_application_names(start, 20).each do |application_name| %>
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><%= resque.aps_notification_count_for_application(application_name) %></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
@@ -1,7 +1,7 @@
1
1
  module Resque
2
2
  module Plugins
3
3
  module Aps
4
- Version = '0.9.15'
4
+ Version = '0.9.17'
5
5
  end
6
6
  end
7
7
  end
@@ -2,7 +2,7 @@ require 'rubygems'
2
2
  require 'resque'
3
3
  require 'logger'
4
4
  require 'resque/server'
5
- require 'resque/plugins/aps'
5
+ require 'resque/plugins/aps/aps'
6
6
  require 'resque/plugins/aps/helper'
7
7
  require 'resque/plugins/aps/version'
8
8
  require 'resque/plugins/aps/server'
@@ -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 File.join(dir, '../lib/resque_aps')
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
- - 15
10
- version: 0.9.15
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: 2010-10-18 00:00:00 -07:00
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
- - --charset=UTF-8
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.7
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