resque-aps 0.9.4 → 0.9.5

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 CHANGED
@@ -1,4 +1,8 @@
1
- ## 0.9.3 (2010-07-08)
1
+ ## 0.9.5 (2010-07-08)
2
+
3
+ * Added Feedback class
4
+
5
+ ## 0.9.4 (2010-07-08)
2
6
 
3
7
  * Use redis.[rpush,lpop,lrange] commands rather than Resque.[push,pop,peek] so that Resque queues are not created for the notifications.
4
8
  * Add a rescue around create_sockets to transform the exception into an application exception before raising it.
@@ -128,12 +128,15 @@ module ResqueAps
128
128
  end
129
129
 
130
130
  def before_aps_write(notification)
131
+ logger.debug("ResqueAps[before_write]: #{notification}") if logger
131
132
  end
132
133
 
133
134
  def after_aps_write(notification)
135
+ logger.debug("ResqueAps[after_write]: #{notification}") if logger
134
136
  end
135
137
 
136
138
  def failed_aps_write(notification, exception)
139
+ logger.error("ResqueAps[write_failed]: #{exception} (#{notification}): #{exception.backtrace.join("\n")}") if logger
137
140
  end
138
141
 
139
142
  def notify_aps_admin(exception)
@@ -143,5 +146,21 @@ module ResqueAps
143
146
  false
144
147
  end
145
148
 
149
+ def before_aps_read
150
+ logger.debug("ResqueAps[before_read]:") if logger
151
+ end
152
+
153
+ def after_aps_read(feedback)
154
+ logger.debug("ResqueAps[after_read]: #{feedback.to_s}") if logger
155
+ end
156
+
157
+ def aps_read_error(exception)
158
+ logger.error("ResqueAps[read_error]: #{exception} (#{application_name}): #{exception.backtrace.join("\n")}") if logger
159
+ end
160
+
161
+ def aps_read_failed
162
+ logger.error("ResqueAps[read_failed]: Bad data on the socket (#{application_name})") if logger
163
+ end
164
+
146
165
  end
147
166
  end
@@ -0,0 +1,88 @@
1
+ require 'timeout'
2
+
3
+ module ResqueAps
4
+ class Feedback
5
+ include ResqueAps::Helper
6
+ extend ResqueAps::Helper
7
+
8
+ @queue = "apple_push_service"
9
+
10
+ attr_accessor :application_name, :device_token, :received_at
11
+
12
+ def initialize(attributes)
13
+ attributes.each do |k, v|
14
+ respond_to?(:"#{k}=") ? send(:"#{k}=", v) : raise(ResqueAps::UnknownAttributeError, "unknown attribute: #{k}")
15
+ end
16
+ end
17
+
18
+ def inspect
19
+ "#<#{self.class.name} #{application_name.inspect}, #{device_token.inspect}, #{received_at.inspect}>"
20
+ end
21
+
22
+ def to_s
23
+ "#{application_name} #{received_at} #{device_token}"
24
+ end
25
+
26
+ def to_hash
27
+ {:application_name => application_name, :device_token => device_token, :received_at => received_at}
28
+ end
29
+
30
+ def self.read_feedback(ssl_socket, application_name, product_id)
31
+ data_str = ssl_socket.read(4)
32
+ return nil unless data_str
33
+ data_ary = data_str.unpack('N')
34
+ return nil unless data_ary && data_ary[0]
35
+ time = Time.at(data_ary[0])
36
+
37
+ data_str = ssl_socket.read(2)
38
+ return nil unless data_str
39
+ data_ary = data_str.unpack('n')
40
+ return nil unless data_ary && data_ary[0]
41
+ tl = data_ary[0]
42
+
43
+ data_str = ssl_socket.read(tl)
44
+ return nil unless data_str
45
+ data_ary = data_str.unpack('H*')
46
+ return nil unless data_ary && data_ary[0]
47
+ token = data_ary[0]
48
+
49
+ feedback = Feedback.new({:received_at => time, :device_token => token, :application_name => application_name})
50
+ return feedback
51
+ end
52
+
53
+ #
54
+ # Perform a Feedback check on the APN server, for the given app key (which must be the first argument)
55
+ #
56
+ def self.perform(*args)
57
+ app_name = args[0]
58
+ start = Time.now
59
+ count = 0
60
+ appl = Resque.aps_application(app_name)
61
+
62
+ return unless appl
63
+
64
+ appl.socket(nil, nil, Resque.aps_feedback_host, Resque.aps_feedback_port) do |socket, app|
65
+ begin
66
+ logger.debug("Feedback: Reading feedbacks for #{app_name}.") if logger
67
+ timeout(5) do
68
+ until socket.eof?
69
+ app.before_aps_read
70
+ feedback = read_feedback(ssl_socket, app_name, product_id)
71
+ if feedback
72
+ count += 1
73
+ app.after_app_read(feedback)
74
+ else
75
+ app.aps_read_failed
76
+ end
77
+ end
78
+ end
79
+ rescue
80
+ logger.error Application.application_exception($!, app_name) if logger
81
+ app.aps_read_error(Application.application_exception($!, app_name))
82
+ end
83
+ end
84
+ logger.info("Read #{count} #{app_name} feedbacks over #{Time.now - start} sec.") if logger
85
+ end
86
+
87
+ end
88
+ end
@@ -12,11 +12,17 @@
12
12
  <tr>
13
13
  <th>Application</th>
14
14
  <th>Notification Count</th>
15
+ <th></th>
15
16
  </tr>
16
17
  <% resque.aps_application_names(start, start+20).each do |application_name| %>
17
18
  <tr>
18
19
  <td><a href="<%= url "aps/#{application_name}" %>"><%= application_name %></a></td>
19
20
  <td><%= resque.aps_notification_count_for_application(application_name) %></td>
21
+ <td>
22
+ <form action="<%= url "/aps/#{application_name}" %>" method="post">
23
+ <input type="submit" value="Queue worker">
24
+ </form>
25
+ </td>
20
26
  </tr>
21
27
  <% end %>
22
28
  </table>
@@ -18,6 +18,10 @@ module ResqueAps
18
18
  erb File.read(File.join(File.dirname(__FILE__), 'server/views/notifications.erb'))
19
19
  end
20
20
 
21
+ post "/aps/:application_name" do
22
+ Resque.enqueue(ResqueAps::Application, params[:application_name])
23
+ redirect url("/aps")
24
+ end
21
25
  end
22
26
 
23
27
  end
@@ -1,3 +1,3 @@
1
1
  module ResqueAps
2
- Version = '0.9.4'
2
+ Version = '0.9.5'
3
3
  end
data/lib/resque_aps.rb CHANGED
@@ -7,6 +7,7 @@ require 'resque_aps/version'
7
7
  require 'resque_aps/server'
8
8
  require 'resque_aps/application'
9
9
  require 'resque_aps/notification'
10
+ require 'resque_aps/feedback'
10
11
  require 'resque_aps/unknown_attribute_error'
11
12
 
12
13
  module ResqueAps
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ context "ResqueAps::Application" do
4
+ test "can perform" do
5
+ Resque.create_aps_application('TestApp', File.dirname(__FILE__) + "/../test-dev.pem", nil)
6
+ ResqueAps::Feedback.perform('TestApp')
7
+ end
8
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 9
8
- - 4
9
- version: 0.9.4
8
+ - 5
9
+ version: 0.9.5
10
10
  platform: ruby
11
11
  authors:
12
12
  - Ashley Martens
@@ -101,6 +101,7 @@ files:
101
101
  - Rakefile
102
102
  - lib/resque_aps.rb
103
103
  - lib/resque_aps/application.rb
104
+ - lib/resque_aps/feedback.rb
104
105
  - lib/resque_aps/helper.rb
105
106
  - lib/resque_aps/notification.rb
106
107
  - lib/resque_aps/server.rb
@@ -112,6 +113,7 @@ files:
112
113
  - lib/resque_aps/version.rb
113
114
  - tasks/resque_aps.rake
114
115
  - test/application_test.rb
116
+ - test/feedback_test.rb
115
117
  - test/notification_test.rb
116
118
  - test/redis-test.conf
117
119
  - test/resque-web_test.rb
@@ -149,6 +151,7 @@ specification_version: 3
149
151
  summary: Queuing system for Apple's Push Service on top of Resque
150
152
  test_files:
151
153
  - test/application_test.rb
154
+ - test/feedback_test.rb
152
155
  - test/notification_test.rb
153
156
  - test/resque-web_test.rb
154
157
  - test/resque_aps_test.rb