rpush 2.0.0.beta2 → 2.0.0.rc1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1 -0
- data/README.md +1 -1
- data/lib/generators/rpush_generator.rb +2 -2
- data/lib/generators/templates/rpush.rb +19 -0
- data/lib/generators/templates/rpush_2_0_0_updates.rb +19 -0
- data/lib/rpush/client/active_model/apns/notification.rb +1 -1
- data/lib/rpush/client/active_model/notification.rb +1 -1
- data/lib/rpush/client/active_record/apns/feedback.rb +3 -1
- data/lib/rpush/client/redis/notification.rb +1 -1
- data/lib/rpush/daemon/adm/delivery.rb +5 -2
- data/lib/rpush/daemon/app_runner.rb +1 -1
- data/lib/rpush/daemon/dispatcher/apns_tcp.rb +10 -2
- data/lib/rpush/daemon/store/active_record/reconnectable.rb +1 -1
- data/lib/rpush/daemon/store/active_record.rb +1 -1
- data/lib/rpush/daemon/store/redis.rb +1 -1
- data/lib/rpush/daemon.rb +2 -2
- data/lib/rpush/reflection.rb +3 -1
- data/lib/rpush/version.rb +1 -1
- data/lib/rpush.rb +1 -1
- data/lib/tasks/quality.rake +6 -5
- data/lib/tasks/test.rake +1 -5
- data/spec/functional/apns_spec.rb +5 -5
- data/spec/functional/embed_spec.rb +1 -3
- data/spec/functional/new_app_spec.rb +1 -3
- data/spec/unit/client/active_record/notification_spec.rb +6 -0
- data/spec/unit/daemon/adm/delivery_spec.rb +8 -0
- data/spec/unit/daemon/apns/feedback_receiver_spec.rb +1 -3
- data/spec/unit/daemon/app_runner_spec.rb +20 -5
- data/spec/unit/daemon/feeder_spec.rb +1 -3
- data/spec/unit/daemon/gcm/delivery_spec.rb +18 -16
- data/spec/unit/daemon/store/active_record/reconnectable_spec.rb +39 -19
- data/spec/unit/daemon/store/active_record_spec.rb +1 -1
- data/spec/unit/daemon/wpns/delivery_spec.rb +1 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0b35cfade151c01d8fc40a3c2c600294eacfbfe0
|
4
|
+
data.tar.gz: e9da0a8194b7916eab23ad91b8158e48f506247f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a5b4463d42d74de9fa8a68cdcc424b0990d7b6e34fae5a920875b042dba246a6901a4666ff2452d6ef37f1325232764537a41ed06b2f8dc318a84ef9ae3b368b
|
7
|
+
data.tar.gz: 0fc2176665da6cabbc9459bd35d1cb7b782771195fd882122808ccad7e35f9303675da12bf0c2c7617c17b4a8bdc271742a8ead20b790711b2d25f6fb5fe0657
|
data/CHANGELOG.md
CHANGED
@@ -10,6 +10,7 @@
|
|
10
10
|
* The 'wakeup' config option has been removed.
|
11
11
|
* The 'batch_storage_updates' config option has been deprecated, storage backends will now always batch updates where appropriate.
|
12
12
|
* The rpush process title updates with number of queued notifications and number of dispatchers.
|
13
|
+
* Rpush::Apns::Feedback#app has been renamed to app_id and is now an Integer.
|
13
14
|
|
14
15
|
## 1.0.0 (Feb 9, 2014)
|
15
16
|
* Renamed to Rpush (from Rapns). Version number reset to 1.0.0.
|
data/README.md
CHANGED
@@ -20,11 +20,11 @@ class RpushGenerator < Rails::Generators::Base
|
|
20
20
|
add_rpush_migration('add_adm')
|
21
21
|
add_rpush_migration('rename_rapns_to_rpush')
|
22
22
|
add_rpush_migration('add_fail_after_to_rpush_notifications')
|
23
|
-
add_rpush_migration('add_processing_to_rpush_notifications')
|
24
23
|
else
|
25
24
|
add_rpush_migration('add_rpush')
|
26
|
-
add_rpush_migration('rpush_2_0_0_updates')
|
27
25
|
end
|
26
|
+
|
27
|
+
add_rpush_migration('rpush_2_0_0_updates')
|
28
28
|
end
|
29
29
|
|
30
30
|
def copy_config
|
@@ -59,12 +59,22 @@ Rpush.reflect do |on|
|
|
59
59
|
# on.notification_failed do |notification|
|
60
60
|
# end
|
61
61
|
|
62
|
+
# Called when the notification delivery failed and only the notification ID
|
63
|
+
# is present in memory.
|
64
|
+
# on.notification_id_failed do |app, notification_id, error_code, error_description|
|
65
|
+
# end
|
66
|
+
|
62
67
|
# Called when a notification will be retried at a later date.
|
63
68
|
# Call 'deliver_after' on the notification for the next delivery date
|
64
69
|
# and 'retries' for the number of times this notification has been retried.
|
65
70
|
# on.notification_will_retry do |notification|
|
66
71
|
# end
|
67
72
|
|
73
|
+
# Called when a notification will be retried and only the notification ID
|
74
|
+
# is present in memory.
|
75
|
+
# on.notification_id_will_retry do |app, notification_id, retry_after|
|
76
|
+
# end
|
77
|
+
|
68
78
|
# Called when a TCP connection is lost and will be reconnected.
|
69
79
|
# on.tcp_connection_lost do |app, error|
|
70
80
|
# end
|
@@ -101,6 +111,15 @@ Rpush.reflect do |on|
|
|
101
111
|
# on.adm_canonical_id do |old_id, canonical_id|
|
102
112
|
# end
|
103
113
|
|
114
|
+
# Called when Failed to deliver to ADM. Check the 'reason' string for further
|
115
|
+
# explanations.
|
116
|
+
#
|
117
|
+
# If the reason is the string 'Unregistered', you should remove
|
118
|
+
# this registration id from your records.
|
119
|
+
# on.adm_failed_to_recipient do |notification, registration_id, reason|
|
120
|
+
# end
|
121
|
+
|
122
|
+
|
104
123
|
# Called when an exception is raised.
|
105
124
|
# on.error do |error|
|
106
125
|
# end
|
@@ -8,9 +8,20 @@ class Rpush200Updates < ActiveRecord::Migration
|
|
8
8
|
end
|
9
9
|
|
10
10
|
add_index :rpush_notifications, [:processing, :delivered, :failed, :deliver_after], name: 'index_rpush_notifications_multi'
|
11
|
+
|
12
|
+
rename_column :rpush_feedback, :app, :app_id
|
13
|
+
|
14
|
+
if postgresql?
|
15
|
+
execute('ALTER TABLE rpush_feedback ALTER COLUMN app_id TYPE integer USING (trim(app_id)::integer)')
|
16
|
+
else
|
17
|
+
change_column :rpush_feedback, :app_id, :integer
|
18
|
+
end
|
11
19
|
end
|
12
20
|
|
13
21
|
def self.down
|
22
|
+
change_column :rpush_feedback, :app_id, :string
|
23
|
+
rename_column :rpush_feedback, :app_id, :app
|
24
|
+
|
14
25
|
if index_name_exists?(:rpush_notifications, :index_rpush_notifications_multi, true)
|
15
26
|
remove_index :rpush_notifications, name: :index_rpush_notifications_multi
|
16
27
|
end
|
@@ -20,4 +31,12 @@ class Rpush200Updates < ActiveRecord::Migration
|
|
20
31
|
remove_column :rpush_notifications, :priority
|
21
32
|
remove_column :rpush_notifications, :processing
|
22
33
|
end
|
34
|
+
|
35
|
+
def self.adapter_name
|
36
|
+
ActiveRecord::Base.configurations[Rails.env]['adapter']
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.postgresql?
|
40
|
+
adapter_name =~ /postgresql/
|
41
|
+
end
|
23
42
|
end
|
@@ -6,9 +6,11 @@ module Rpush
|
|
6
6
|
self.table_name = 'rpush_feedback'
|
7
7
|
|
8
8
|
if Rpush.attr_accessible_available?
|
9
|
-
attr_accessible :device_token, :failed_at, :
|
9
|
+
attr_accessible :device_token, :failed_at, :app_id
|
10
10
|
end
|
11
11
|
|
12
|
+
belongs_to :app, class_name: 'Rpush::Client::ActiveRecord::App'
|
13
|
+
|
12
14
|
validates :device_token, presence: true
|
13
15
|
validates :failed_at, presence: true
|
14
16
|
|
@@ -21,7 +21,7 @@ module Rpush
|
|
21
21
|
attribute :badge, :integer
|
22
22
|
attribute :device_token, :string
|
23
23
|
attribute :sound, :string, default: 'default'
|
24
|
-
attribute :alert, :hash, strict: false
|
24
|
+
attribute :alert, [:string, :hash], strict: false
|
25
25
|
attribute :data, :hash
|
26
26
|
attribute :expiry, :integer, default: 1.day.to_i
|
27
27
|
attribute :delivered, :boolean
|
@@ -120,8 +120,11 @@ module Rpush
|
|
120
120
|
|
121
121
|
return unless response_body.key?('reason')
|
122
122
|
|
123
|
-
|
124
|
-
|
123
|
+
reason = response_body['reason']
|
124
|
+
log_warn("bad_request: #{current_registration_id} (#{reason})")
|
125
|
+
@failed_registration_ids[current_registration_id] = reason
|
126
|
+
|
127
|
+
reflect(:adm_failed_to_recipient, @notification, current_registration_id, reason)
|
125
128
|
end
|
126
129
|
|
127
130
|
def unauthorized(response)
|
@@ -98,7 +98,7 @@ module Rpush
|
|
98
98
|
|
99
99
|
def enqueue(notifications)
|
100
100
|
if service.batch_deliveries?
|
101
|
-
batch_size = (notifications.size / num_dispatcher_loops).ceil
|
101
|
+
batch_size = (notifications.size / num_dispatcher_loops.to_f).ceil
|
102
102
|
notifications.in_groups_of(batch_size, false).each do |batch_notifications|
|
103
103
|
batch = Batch.new(batch_notifications)
|
104
104
|
queue.push(QueuePayload.new(batch))
|
@@ -3,6 +3,7 @@ module Rpush
|
|
3
3
|
module Dispatcher
|
4
4
|
class ApnsTcp < Rpush::Daemon::Dispatcher::Tcp
|
5
5
|
include Loggable
|
6
|
+
include Reflectable
|
6
7
|
|
7
8
|
SELECT_TIMEOUT = 10
|
8
9
|
ERROR_TUPLE_BYTES = 6
|
@@ -85,17 +86,24 @@ module Rpush
|
|
85
86
|
|
86
87
|
def handle_disconnect
|
87
88
|
log_error('The APNs disconnected without returning an error. Marking all notifications delivered via this connection as failed.')
|
88
|
-
|
89
|
+
reason = 'The APNs disconnected without returning an error. This may indicate you are using an invalid certificate.'
|
90
|
+
Rpush::Daemon.store.mark_ids_failed(delivered_buffer, nil, reason, Time.now)
|
91
|
+
delivered_buffer.each { |id| reflect(:notification_id_failed, @app, id, nil, reason) }
|
89
92
|
end
|
90
93
|
|
91
94
|
def handle_error(code, notification_id)
|
92
95
|
failed_pos = delivered_buffer.index(notification_id)
|
93
96
|
description = APNS_ERRORS[code.to_i] || "Unknown error code #{code.inspect}. Possible Rpush bug?"
|
94
97
|
Rpush::Daemon.store.mark_ids_failed([notification_id], code, description, Time.now)
|
98
|
+
reflect(:notification_id_failed, @app, notification_id, code, description)
|
95
99
|
|
96
100
|
if failed_pos
|
97
101
|
retry_ids = delivered_buffer[(failed_pos + 1)..-1]
|
98
|
-
|
102
|
+
if retry_ids.size > 0
|
103
|
+
now = Time.now
|
104
|
+
Rpush::Daemon.store.mark_ids_retryable(retry_ids, now)
|
105
|
+
retry_ids.each { |id| reflect(:notification_id_will_retry, @app, id, now) }
|
106
|
+
end
|
99
107
|
elsif delivered_buffer.size > 0
|
100
108
|
log_error("Delivery sequence unknown for notifications following #{notification_id}.")
|
101
109
|
end
|
@@ -22,7 +22,7 @@ module Rpush
|
|
22
22
|
module Reconnectable
|
23
23
|
ADAPTER_ERRORS = [::ActiveRecord::StatementInvalid, PGError, PG::Error,
|
24
24
|
Mysql::Error, Mysql2::Error, ::ActiveRecord::JDBCError,
|
25
|
-
SQLite3::Exception]
|
25
|
+
SQLite3::Exception, ::ActiveRecord::ConnectionTimeoutError]
|
26
26
|
|
27
27
|
def with_database_reconnect_and_retry
|
28
28
|
::ActiveRecord::Base.connection_pool.with_connection do
|
@@ -119,7 +119,7 @@ module Rpush
|
|
119
119
|
def create_apns_feedback(failed_at, device_token, app)
|
120
120
|
with_database_reconnect_and_retry do
|
121
121
|
Rpush::Client::ActiveRecord::Apns::Feedback.create!(failed_at: failed_at,
|
122
|
-
device_token: device_token,
|
122
|
+
device_token: device_token, app_id: app.id)
|
123
123
|
end
|
124
124
|
end
|
125
125
|
|
@@ -79,7 +79,7 @@ module Rpush
|
|
79
79
|
end
|
80
80
|
|
81
81
|
def create_apns_feedback(failed_at, device_token, app)
|
82
|
-
Rpush::Client::Redis::Apns::Feedback.create!(failed_at: failed_at, device_token: device_token,
|
82
|
+
Rpush::Client::Redis::Apns::Feedback.create!(failed_at: failed_at, device_token: device_token, app_id: app.id)
|
83
83
|
end
|
84
84
|
|
85
85
|
def create_gcm_notification(attrs, data, registration_ids, deliver_after, app) # rubocop:disable ParameterLists
|
data/lib/rpush/daemon.rb
CHANGED
data/lib/rpush/reflection.rb
CHANGED
@@ -14,7 +14,9 @@ module Rpush
|
|
14
14
|
:apns_feedback, :notification_enqueued, :notification_delivered,
|
15
15
|
:notification_failed, :notification_will_retry, :gcm_delivered_to_recipient,
|
16
16
|
:gcm_failed_to_recipient, :gcm_canonical_id, :gcm_invalid_registration_id,
|
17
|
-
:error, :adm_canonical_id, :
|
17
|
+
:error, :adm_canonical_id, :adm_failed_to_recipient,
|
18
|
+
:tcp_connection_lost, :ssl_certificate_will_expire,
|
19
|
+
:notification_id_will_retry, :notification_id_failed
|
18
20
|
]
|
19
21
|
|
20
22
|
DEPRECATIONS = {}
|
data/lib/rpush/version.rb
CHANGED
data/lib/rpush.rb
CHANGED
data/lib/tasks/quality.rake
CHANGED
@@ -11,24 +11,25 @@ begin
|
|
11
11
|
end
|
12
12
|
|
13
13
|
namespace :spec do
|
14
|
-
task :
|
14
|
+
task cane: %w(spec cane_quality)
|
15
15
|
end
|
16
16
|
rescue LoadError
|
17
17
|
warn "cane not available."
|
18
18
|
|
19
19
|
namespace :spec do
|
20
|
-
task :
|
20
|
+
task cane: ['spec']
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
begin
|
25
25
|
require 'rubocop/rake_task'
|
26
|
-
RuboCop::RakeTask.new
|
26
|
+
t = RuboCop::RakeTask.new
|
27
|
+
t.options << '-D'
|
27
28
|
rescue LoadError
|
28
29
|
warn 'rubocop not available.'
|
29
|
-
task :
|
30
|
+
task rubocop: ['spec']
|
30
31
|
end
|
31
32
|
|
32
33
|
namespace :spec do
|
33
|
-
task quality:
|
34
|
+
task quality: %w(cane rubocop)
|
34
35
|
end
|
data/lib/tasks/test.rake
CHANGED
@@ -4,11 +4,7 @@ namespace :test do
|
|
4
4
|
|
5
5
|
def cmd(str, clean_env = true)
|
6
6
|
puts "* #{str}"
|
7
|
-
retval =
|
8
|
-
Bundler.with_clean_env { `#{str}` }
|
9
|
-
else
|
10
|
-
`#{str}`
|
11
|
-
end
|
7
|
+
retval = clean_env ? Bundler.with_clean_env { `#{str}` } : `#{str}`
|
12
8
|
puts retval.strip
|
13
9
|
retval
|
14
10
|
end
|
@@ -5,9 +5,7 @@ describe 'APNs' do
|
|
5
5
|
let(:app) { create_app }
|
6
6
|
let!(:notification) { create_notification }
|
7
7
|
let(:tcp_socket) { double(TCPSocket, setsockopt: nil, close: nil) }
|
8
|
-
let(:ssl_socket)
|
9
|
-
write: nil, flush: nil, read: nil, close: nil)
|
10
|
-
end
|
8
|
+
let(:ssl_socket) { double(OpenSSL::SSL::SSLSocket, :sync= => nil, connect: nil, write: nil, flush: nil, read: nil, close: nil) }
|
11
9
|
let(:io_double) { double(select: nil) }
|
12
10
|
|
13
11
|
before do
|
@@ -92,8 +90,10 @@ describe 'APNs' do
|
|
92
90
|
tuple = "N\xE3\x84\r\x00 \x83OxfU\xEB\x9F\x84aJ\x05\xAD}\x00\xAF1\xE5\xCF\xE9:\xC3\xEA\a\x8F\x1D\xA4M*N\xB0\xCE\x17"
|
93
91
|
allow(ssl_socket).to receive(:read).and_return(tuple, nil)
|
94
92
|
Rpush.apns_feedback
|
95
|
-
feedback = Rpush::Apns::Feedback.all
|
96
|
-
feedback.should_not
|
93
|
+
feedback = Rpush::Apns::Feedback.all.first
|
94
|
+
feedback.should_not be_nil
|
95
|
+
feedback.app_id.should eq(app.id)
|
96
|
+
feedback.device_token.should eq('834f786655eb9f84614a05ad7d00af31e5cfe93ac3ea078f1da44d2a4eb0ce17')
|
97
97
|
end
|
98
98
|
|
99
99
|
describe 'delivery failures' do
|
@@ -5,9 +5,7 @@ describe 'embedding' do
|
|
5
5
|
let(:app) { Rpush::Apns::App.new }
|
6
6
|
let(:notification) { Rpush::Apns::Notification.new }
|
7
7
|
let(:tcp_socket) { double(TCPSocket, setsockopt: nil, close: nil) }
|
8
|
-
let(:ssl_socket)
|
9
|
-
write: nil, flush: nil, read: nil, close: nil)
|
10
|
-
end
|
8
|
+
let(:ssl_socket) { double(OpenSSL::SSL::SSLSocket, :sync= => nil, connect: nil, write: nil, flush: nil, read: nil, close: nil) }
|
11
9
|
let(:io_double) { double(select: nil) }
|
12
10
|
|
13
11
|
before do
|
@@ -4,9 +4,7 @@ describe 'New app loading' do
|
|
4
4
|
let(:timeout) { 10 }
|
5
5
|
let(:app) { create_app }
|
6
6
|
let(:tcp_socket) { double(TCPSocket, setsockopt: nil, close: nil) }
|
7
|
-
let(:ssl_socket)
|
8
|
-
write: nil, flush: nil, read: nil, close: nil)
|
9
|
-
end
|
7
|
+
let(:ssl_socket) { double(OpenSSL::SSL::SSLSocket, :sync= => nil, connect: nil, write: nil, flush: nil, read: nil, close: nil) }
|
10
8
|
let(:io_double) { double(select: nil) }
|
11
9
|
|
12
10
|
before do
|
@@ -12,4 +12,10 @@ describe Rpush::Client::ActiveRecord::Notification do
|
|
12
12
|
notification.registration_ids = 'a'
|
13
13
|
notification.registration_ids.should eq ['a']
|
14
14
|
end
|
15
|
+
|
16
|
+
it 'saves its parent App if required' do
|
17
|
+
notification.app = Rpush::Client::ActiveRecord::App.new(name: "aname")
|
18
|
+
expect(notification.app).to be_valid
|
19
|
+
expect(notification).to be_valid
|
20
|
+
end
|
15
21
|
end
|
@@ -80,6 +80,14 @@ describe Rpush::Daemon::Adm::Delivery do
|
|
80
80
|
logger.should_receive(:warn).with("[MyApp] bad_request: xyz (InvalidRegistrationId)")
|
81
81
|
expect { perform }.to raise_error
|
82
82
|
end
|
83
|
+
|
84
|
+
it 'reflects' do
|
85
|
+
response.stub(body: JSON.dump('registrationID' => 'canonical123', 'reason' => 'Unregistered'))
|
86
|
+
notification.stub(registration_ids: ['1'])
|
87
|
+
delivery.should_receive(:reflect).with(:adm_failed_to_recipient, notification, '1', 'Unregistered')
|
88
|
+
expect { perform }.to raise_error
|
89
|
+
end
|
90
|
+
|
83
91
|
end
|
84
92
|
|
85
93
|
describe 'a 401 (Unauthorized) response' do
|
@@ -14,9 +14,7 @@ describe Rpush::Daemon::Apns::FeedbackReceiver, 'check_for_feedback' do
|
|
14
14
|
let(:receiver) { Rpush::Daemon::Apns::FeedbackReceiver.new(app) }
|
15
15
|
let(:feedback) { double }
|
16
16
|
let(:sleeper) { double(Rpush::Daemon::InterruptibleSleep, sleep: nil, start: nil, stop: nil) }
|
17
|
-
let(:store)
|
18
|
-
create_apns_feedback: feedback, release_connection: nil)
|
19
|
-
end
|
17
|
+
let(:store) { double(Rpush::Daemon::Store::ActiveRecord, create_apns_feedback: feedback, release_connection: nil) }
|
20
18
|
|
21
19
|
before do
|
22
20
|
Rpush.config.feedback_poll = poll
|
@@ -78,8 +78,9 @@ describe Rpush::Daemon::AppRunner, 'start_app' do
|
|
78
78
|
end
|
79
79
|
|
80
80
|
describe Rpush::Daemon::AppRunner, 'debug' do
|
81
|
-
let(:app) do
|
82
|
-
|
81
|
+
let(:app) do
|
82
|
+
double(Rpush::AppRunnerSpecService::App, id: 1, name: 'test', connections: 1,
|
83
|
+
environment: 'development', certificate: TEST_CERT, service_name: 'app_runner_spec_service')
|
83
84
|
end
|
84
85
|
let(:logger) { double(Rpush::Logger, info: nil) }
|
85
86
|
let(:store) { double(all_apps: [app], release_connection: nil) }
|
@@ -99,9 +100,9 @@ describe Rpush::Daemon::AppRunner, 'debug' do
|
|
99
100
|
end
|
100
101
|
|
101
102
|
describe Rpush::Daemon::AppRunner do
|
102
|
-
let(:app) do
|
103
|
-
|
104
|
-
|
103
|
+
let(:app) do
|
104
|
+
double(Rpush::AppRunnerSpecService::App, environment: :sandbox,
|
105
|
+
connections: 1, service_name: 'app_runner_spec_service', name: 'test')
|
105
106
|
end
|
106
107
|
let(:runner) { Rpush::Daemon::AppRunner.new(app) }
|
107
108
|
let(:logger) { double(Rpush::Logger, info: nil) }
|
@@ -151,6 +152,20 @@ describe Rpush::Daemon::AppRunner do
|
|
151
152
|
runner.should_receive(:reflect).with(:notification_enqueued, notification)
|
152
153
|
runner.enqueue([notification])
|
153
154
|
end
|
155
|
+
|
156
|
+
describe 'a service that batches deliveries' do
|
157
|
+
before do
|
158
|
+
runner.send(:service).stub(batch_deliveries?: true)
|
159
|
+
end
|
160
|
+
|
161
|
+
describe '1 notification with more than one dispatcher loop' do
|
162
|
+
it 'does not raise ArgumentError: invalid slice size' do
|
163
|
+
# https://github.com/rpush/rpush/issues/57
|
164
|
+
runner.stub(:num_dispatcher_loops).and_return(2)
|
165
|
+
runner.enqueue([notification])
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
154
169
|
end
|
155
170
|
|
156
171
|
describe 'stop' do
|
@@ -5,9 +5,7 @@ describe Rpush::Daemon::Feeder do
|
|
5
5
|
let(:notification) { Rpush::Apns::Notification.create!(device_token: "a" * 64, app: app) }
|
6
6
|
let(:logger) { double }
|
7
7
|
let(:interruptible_sleeper) { double(sleep: nil, stop: nil, start: nil) }
|
8
|
-
let(:store)
|
9
|
-
deliverable_notifications: [notification], release_connection: nil)
|
10
|
-
end
|
8
|
+
let(:store) { double(Rpush::Daemon::Store::ActiveRecord, deliverable_notifications: [notification], release_connection: nil) }
|
11
9
|
|
12
10
|
before do
|
13
11
|
Rpush.configure do |config|
|
@@ -224,28 +224,30 @@ describe Rpush::Daemon::Gcm::Delivery do
|
|
224
224
|
end
|
225
225
|
|
226
226
|
describe 'all deliveries failed with some as Unavailable or InternalServerError' do
|
227
|
-
let(:body) do
|
228
|
-
'failure' => 3,
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
227
|
+
let(:body) do
|
228
|
+
{ 'failure' => 3,
|
229
|
+
'success' => 0,
|
230
|
+
'results' => [
|
231
|
+
{ 'error' => 'Unavailable' },
|
232
|
+
{ 'error' => 'InvalidDataKey' },
|
233
|
+
{ 'error' => 'Unavailable' }
|
234
|
+
]
|
235
|
+
}
|
235
236
|
end
|
236
237
|
let(:error_description) { /#{Regexp.escape("Failed to deliver to recipients 0, 1, 2. Errors: Unavailable, InvalidDataKey, Unavailable. 0, 2 will be retried as notification")} [\d]+\./ }
|
237
238
|
it_should_behave_like 'a notification with some delivery failures'
|
238
239
|
end
|
239
240
|
|
240
241
|
describe 'some deliveries failed with Unavailable or InternalServerError' do
|
241
|
-
let(:body) do
|
242
|
-
'failure' => 2,
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
242
|
+
let(:body) do
|
243
|
+
{ 'failure' => 2,
|
244
|
+
'success' => 1,
|
245
|
+
'results' => [
|
246
|
+
{ 'error' => 'Unavailable' },
|
247
|
+
{ 'message_id' => '1:000' },
|
248
|
+
{ 'error' => 'InternalServerError' }
|
249
|
+
]
|
250
|
+
}
|
249
251
|
end
|
250
252
|
let(:error_description) { /#{Regexp.escape("Failed to deliver to recipients 0, 2. Errors: Unavailable, InternalServerError. 0, 2 will be retried as notification")} [\d]+\./ }
|
251
253
|
it_should_behave_like 'a notification with some delivery failures'
|
@@ -43,7 +43,8 @@ describe Rpush::Daemon::Store::ActiveRecord::Reconnectable do
|
|
43
43
|
end
|
44
44
|
|
45
45
|
let(:error) { adapter_error_class.new("db down!") }
|
46
|
-
let(:
|
46
|
+
let(:timeout) { ActiveRecord::ConnectionTimeoutError.new("db lazy!") }
|
47
|
+
let(:test_doubles) { [TestDouble.new(error, 1), TestDouble.new(timeout, 1)] }
|
47
48
|
|
48
49
|
before do
|
49
50
|
@logger = double("Logger", info: nil, error: nil, warn: nil)
|
@@ -51,37 +52,37 @@ describe Rpush::Daemon::Store::ActiveRecord::Reconnectable do
|
|
51
52
|
|
52
53
|
ActiveRecord::Base.stub(:clear_all_connections!)
|
53
54
|
ActiveRecord::Base.stub(:establish_connection)
|
54
|
-
|
55
|
+
test_doubles.each { |td| allow(td).to receive(:sleep) }
|
55
56
|
end
|
56
57
|
|
57
58
|
it "should log the error raised" do
|
58
59
|
Rpush.logger.should_receive(:error).with(error)
|
59
|
-
|
60
|
+
test_doubles.each(&:perform)
|
60
61
|
end
|
61
62
|
|
62
63
|
it "should log that the database is being reconnected" do
|
63
64
|
Rpush.logger.should_receive(:warn).with("Lost connection to database, reconnecting...")
|
64
|
-
|
65
|
+
test_doubles.each(&:perform)
|
65
66
|
end
|
66
67
|
|
67
68
|
it "should log the reconnection attempt" do
|
68
69
|
Rpush.logger.should_receive(:warn).with("Attempt 1")
|
69
|
-
|
70
|
+
test_doubles.each(&:perform)
|
70
71
|
end
|
71
72
|
|
72
73
|
it "should clear all connections" do
|
73
74
|
ActiveRecord::Base.should_receive(:clear_all_connections!)
|
74
|
-
|
75
|
+
test_doubles.each(&:perform)
|
75
76
|
end
|
76
77
|
|
77
78
|
it "should establish a new connection" do
|
78
79
|
ActiveRecord::Base.should_receive(:establish_connection)
|
79
|
-
|
80
|
+
test_doubles.each(&:perform)
|
80
81
|
end
|
81
82
|
|
82
83
|
it "should test out the new connection by performing a count" do
|
83
|
-
Rpush::Client::ActiveRecord::Notification.should_receive(:count)
|
84
|
-
|
84
|
+
Rpush::Client::ActiveRecord::Notification.should_receive(:count).twice
|
85
|
+
test_doubles.each(&:perform)
|
85
86
|
end
|
86
87
|
|
87
88
|
context "when the reconnection attempt is not successful" do
|
@@ -97,19 +98,38 @@ describe Rpush::Daemon::Store::ActiveRecord::Reconnectable do
|
|
97
98
|
Rpush::Client::ActiveRecord::Notification.instance_variable_set("@error", error)
|
98
99
|
end
|
99
100
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
101
|
+
describe "error behaviour" do
|
102
|
+
it "should log the 2nd attempt" do
|
103
|
+
Rpush.logger.should_receive(:warn).with("Attempt 2")
|
104
|
+
test_doubles[0].perform
|
105
|
+
end
|
104
106
|
|
105
|
-
|
106
|
-
|
107
|
-
|
107
|
+
it "should log errors raised when the reconnection is not successful" do
|
108
|
+
Rpush.logger.should_receive(:error).with(error)
|
109
|
+
test_doubles[0].perform
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should sleep to avoid thrashing when the database is down" do
|
113
|
+
expect(test_doubles[0]).to receive(:sleep).with(2)
|
114
|
+
test_doubles[0].perform
|
115
|
+
end
|
108
116
|
end
|
109
117
|
|
110
|
-
|
111
|
-
|
112
|
-
|
118
|
+
describe "timeout behaviour" do
|
119
|
+
it "should log the 2nd attempt" do
|
120
|
+
Rpush.logger.should_receive(:warn).with("Attempt 2")
|
121
|
+
test_doubles[1].perform
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should log errors raised when the reconnection is not successful" do
|
125
|
+
Rpush.logger.should_receive(:error).with(error)
|
126
|
+
test_doubles[1].perform
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should sleep to avoid thrashing when the database is down" do
|
130
|
+
expect(test_doubles[1]).to receive(:sleep).with(2)
|
131
|
+
test_doubles[1].perform
|
132
|
+
end
|
113
133
|
end
|
114
134
|
end
|
115
135
|
end
|
@@ -273,7 +273,7 @@ describe Rpush::Daemon::Store::ActiveRecord do
|
|
273
273
|
describe 'create_apns_feedback' do
|
274
274
|
it 'creates the Feedback record' do
|
275
275
|
Rpush::Client::ActiveRecord::Apns::Feedback.should_receive(:create!).with(
|
276
|
-
failed_at: time, device_token: 'ab' * 32,
|
276
|
+
failed_at: time, device_token: 'ab' * 32, app_id: app.id)
|
277
277
|
store.create_apns_feedback(time, 'ab' * 32, app)
|
278
278
|
end
|
279
279
|
end
|
@@ -2,10 +2,7 @@ require 'unit_spec_helper'
|
|
2
2
|
|
3
3
|
describe Rpush::Daemon::Wpns::Delivery do
|
4
4
|
let(:app) { Rpush::Wpns::App.create!(name: "MyApp") }
|
5
|
-
let(:notification)
|
6
|
-
uri: "http://some.example/",
|
7
|
-
deliver_after: Time.now)
|
8
|
-
end
|
5
|
+
let(:notification) { Rpush::Wpns::Notification.create!(app: app, alert: "test", uri: "http://some.example/", deliver_after: Time.now) }
|
9
6
|
let(:logger) { double(error: nil, info: nil, warn: nil) }
|
10
7
|
let(:response) { double(code: 200, header: {}) }
|
11
8
|
let(:http) { double(shutdown: nil, request: response) }
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rpush
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.
|
4
|
+
version: 2.0.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ian Leitch
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-09-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: multi_json
|