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 +5 -1
- data/lib/resque_aps/application.rb +19 -0
- data/lib/resque_aps/feedback.rb +88 -0
- data/lib/resque_aps/server/views/aps_applications.erb +6 -0
- data/lib/resque_aps/server.rb +4 -0
- data/lib/resque_aps/version.rb +1 -1
- data/lib/resque_aps.rb +1 -0
- data/test/feedback_test.rb +8 -0
- metadata +5 -2
data/HISTORY.md
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
-
## 0.9.
|
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>
|
data/lib/resque_aps/server.rb
CHANGED
@@ -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
|
data/lib/resque_aps/version.rb
CHANGED
data/lib/resque_aps.rb
CHANGED
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 9
|
8
|
-
-
|
9
|
-
version: 0.9.
|
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
|