resque-aps 0.9.4 → 0.9.5

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