rpush 1.0.0 → 2.0.0.beta1
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 +13 -0
- data/README.md +12 -14
- data/bin/rpush +11 -2
- data/lib/generators/rpush_generator.rb +2 -0
- data/lib/generators/templates/add_adm.rb +5 -5
- data/lib/generators/templates/add_alert_is_json_to_rapns_notifications.rb +1 -1
- data/lib/generators/templates/add_app_to_rapns.rb +2 -2
- data/lib/generators/templates/add_fail_after_to_rpush_notifications.rb +1 -1
- data/lib/generators/templates/add_gcm.rb +32 -32
- data/lib/generators/templates/add_rpush.rb +67 -67
- data/lib/generators/templates/add_wpns.rb +2 -2
- data/lib/generators/templates/create_rapns_apps.rb +5 -5
- data/lib/generators/templates/create_rapns_feedback.rb +2 -2
- data/lib/generators/templates/create_rapns_notifications.rb +15 -15
- data/lib/generators/templates/rpush.rb +10 -7
- data/lib/generators/templates/rpush_2_0_0_updates.rb +23 -0
- data/lib/rpush.rb +4 -28
- data/lib/rpush/client/active_model.rb +21 -0
- data/lib/rpush/client/active_model/adm/app.rb +23 -0
- data/lib/rpush/client/active_model/adm/data_validator.rb +14 -0
- data/lib/rpush/client/active_model/adm/notification.rb +28 -0
- data/lib/rpush/client/active_model/apns/app.rb +37 -0
- data/lib/rpush/client/active_model/apns/binary_notification_validator.rb +16 -0
- data/lib/rpush/client/active_model/apns/device_token_format_validator.rb +14 -0
- data/lib/rpush/client/active_model/apns/notification.rb +90 -0
- data/lib/rpush/client/active_model/gcm/app.rb +19 -0
- data/lib/rpush/client/active_model/gcm/expiry_collapse_key_mutual_inclusion_validator.rb +14 -0
- data/lib/rpush/client/active_model/gcm/notification.rb +31 -0
- data/lib/rpush/client/active_model/notification.rb +26 -0
- data/lib/rpush/client/active_model/payload_data_size_validator.rb +13 -0
- data/lib/rpush/client/active_model/registration_ids_count_validator.rb +13 -0
- data/lib/rpush/client/active_model/wpns/app.rb +13 -0
- data/lib/rpush/client/active_model/wpns/notification.rb +17 -0
- data/lib/rpush/client/active_record.rb +19 -0
- data/lib/rpush/client/active_record/adm/app.rb +11 -0
- data/lib/rpush/client/active_record/adm/notification.rb +11 -0
- data/lib/rpush/client/active_record/apns/app.rb +11 -0
- data/lib/rpush/client/active_record/apns/feedback.rb +20 -0
- data/lib/rpush/client/active_record/apns/notification.rb +46 -0
- data/lib/rpush/client/active_record/app.rb +17 -0
- data/lib/rpush/client/active_record/gcm/app.rb +11 -0
- data/lib/rpush/client/active_record/gcm/notification.rb +11 -0
- data/lib/rpush/client/active_record/notification.rb +38 -0
- data/lib/rpush/client/active_record/wpns/app.rb +11 -0
- data/lib/rpush/client/active_record/wpns/notification.rb +11 -0
- data/lib/rpush/client/redis.rb +35 -0
- data/lib/rpush/client/redis/adm/app.rb +14 -0
- data/lib/rpush/client/redis/adm/notification.rb +11 -0
- data/lib/rpush/client/redis/apns/app.rb +11 -0
- data/lib/rpush/client/redis/apns/feedback.rb +20 -0
- data/lib/rpush/client/redis/apns/notification.rb +11 -0
- data/lib/rpush/client/redis/app.rb +22 -0
- data/lib/rpush/client/redis/gcm/app.rb +11 -0
- data/lib/rpush/client/redis/gcm/notification.rb +11 -0
- data/lib/rpush/client/redis/notification.rb +68 -0
- data/lib/rpush/client/redis/wpns/app.rb +11 -0
- data/lib/rpush/client/redis/wpns/notification.rb +11 -0
- data/lib/rpush/configuration.rb +27 -6
- data/lib/rpush/daemon.rb +36 -56
- data/lib/rpush/daemon/adm/delivery.rb +50 -52
- data/lib/rpush/daemon/apns.rb +6 -5
- data/lib/rpush/daemon/apns/delivery.rb +20 -44
- data/lib/rpush/daemon/apns/feedback_receiver.rb +11 -8
- data/lib/rpush/daemon/app_runner.rb +67 -60
- data/lib/rpush/daemon/batch.rb +54 -40
- data/lib/rpush/daemon/delivery.rb +13 -3
- data/lib/rpush/daemon/delivery_error.rb +10 -2
- data/lib/rpush/daemon/dispatcher/apns_tcp.rb +106 -0
- data/lib/rpush/daemon/dispatcher/http.rb +3 -3
- data/lib/rpush/daemon/dispatcher/tcp.rb +3 -3
- data/lib/rpush/daemon/dispatcher_loop.rb +15 -6
- data/lib/rpush/daemon/errors.rb +18 -0
- data/lib/rpush/daemon/feeder.rb +28 -39
- data/lib/rpush/daemon/gcm/delivery.rb +19 -20
- data/lib/rpush/daemon/interruptible_sleep.rb +26 -45
- data/lib/rpush/daemon/loggable.rb +2 -4
- data/lib/rpush/daemon/proc_title.rb +16 -0
- data/lib/rpush/daemon/queue_payload.rb +12 -0
- data/lib/rpush/daemon/reflectable.rb +3 -5
- data/lib/rpush/daemon/retry_header_parser.rb +6 -6
- data/lib/rpush/daemon/ring_buffer.rb +16 -0
- data/lib/rpush/daemon/service_config_methods.rb +23 -7
- data/lib/rpush/daemon/signal_handler.rb +51 -0
- data/lib/rpush/daemon/store/active_record.rb +71 -38
- data/lib/rpush/daemon/store/active_record/reconnectable.rb +15 -15
- data/lib/rpush/daemon/store/interface.rb +19 -0
- data/lib/rpush/daemon/store/redis.rb +149 -0
- data/lib/rpush/daemon/tcp_connection.rb +6 -11
- data/lib/rpush/daemon/wpns/delivery.rb +21 -30
- data/lib/rpush/deprecatable.rb +4 -3
- data/lib/rpush/deprecation.rb +7 -10
- data/lib/rpush/embed.rb +7 -2
- data/lib/rpush/logger.rb +11 -15
- data/lib/rpush/push.rb +0 -1
- data/lib/rpush/reflection.rb +6 -12
- data/lib/rpush/version.rb +1 -1
- data/lib/tasks/quality.rake +34 -0
- data/spec/.rubocop.yml +4 -0
- data/spec/functional/adm_spec.rb +3 -6
- data/spec/functional/apns_spec.rb +118 -24
- data/spec/functional/embed_spec.rb +22 -20
- data/spec/functional/gcm_spec.rb +4 -7
- data/spec/functional/new_app_spec.rb +61 -0
- data/spec/functional/retry_spec.rb +46 -0
- data/spec/functional/wpns_spec.rb +3 -6
- data/spec/functional_spec_helper.rb +26 -0
- data/spec/integration/rpush_spec.rb +13 -0
- data/spec/integration/support/gcm_success_response.json +1 -0
- data/spec/spec_helper.rb +60 -0
- data/spec/support/active_record_setup.rb +48 -0
- data/{config → spec/support/config}/database.yml +0 -0
- data/spec/support/install.sh +43 -7
- data/spec/support/simplecov_helper.rb +9 -5
- data/spec/support/simplecov_quality_formatter.rb +10 -6
- data/spec/unit/apns_feedback_spec.rb +3 -3
- data/spec/unit/{adm → client/active_record/adm}/app_spec.rb +3 -3
- data/spec/unit/{adm → client/active_record/adm}/notification_spec.rb +5 -7
- data/spec/unit/client/active_record/apns/app_spec.rb +29 -0
- data/spec/unit/client/active_record/apns/feedback_spec.rb +9 -0
- data/spec/unit/client/active_record/apns/notification_spec.rb +231 -0
- data/spec/unit/client/active_record/app_spec.rb +30 -0
- data/spec/unit/client/active_record/gcm/app_spec.rb +4 -0
- data/spec/unit/{gcm → client/active_record/gcm}/notification_spec.rb +5 -7
- data/spec/unit/client/active_record/notification_spec.rb +15 -0
- data/spec/unit/client/active_record/wpns/app_spec.rb +4 -0
- data/spec/unit/client/active_record/wpns/notification_spec.rb +21 -0
- data/spec/unit/configuration_spec.rb +12 -5
- data/spec/unit/daemon/adm/delivery_spec.rb +57 -54
- data/spec/unit/daemon/apns/certificate_expired_error_spec.rb +3 -3
- data/spec/unit/daemon/apns/delivery_spec.rb +90 -83
- data/spec/unit/daemon/apns/feedback_receiver_spec.rb +24 -17
- data/spec/unit/daemon/app_runner_spec.rb +66 -123
- data/spec/unit/daemon/batch_spec.rb +52 -115
- data/spec/unit/daemon/delivery_spec.rb +15 -1
- data/spec/unit/daemon/dispatcher/http_spec.rb +3 -2
- data/spec/unit/daemon/dispatcher/tcp_spec.rb +10 -9
- data/spec/unit/daemon/dispatcher_loop_spec.rb +7 -12
- data/spec/unit/daemon/feeder_spec.rb +40 -39
- data/spec/unit/daemon/gcm/delivery_spec.rb +108 -89
- data/spec/unit/daemon/reflectable_spec.rb +2 -2
- data/spec/unit/daemon/retryable_error_spec.rb +1 -1
- data/spec/unit/daemon/service_config_methods_spec.rb +6 -3
- data/spec/unit/daemon/signal_handler_spec.rb +72 -0
- data/spec/unit/daemon/store/active_record/reconnectable_spec.rb +9 -9
- data/spec/unit/daemon/store/active_record_spec.rb +38 -47
- data/spec/unit/daemon/tcp_connection_spec.rb +22 -34
- data/spec/unit/daemon/too_many_requests_error_spec.rb +1 -1
- data/spec/unit/daemon/wpns/delivery_spec.rb +61 -50
- data/spec/unit/daemon_spec.rb +46 -81
- data/spec/unit/embed_spec.rb +4 -2
- data/spec/unit/logger_spec.rb +30 -40
- data/spec/unit/notification_shared.rb +9 -79
- data/spec/unit/push_spec.rb +3 -8
- data/spec/unit/reflection_spec.rb +25 -25
- data/spec/unit/rpush_spec.rb +1 -2
- data/spec/unit_spec_helper.rb +33 -88
- metadata +119 -67
- data/lib/rpush/TODO +0 -3
- data/lib/rpush/adm/app.rb +0 -15
- data/lib/rpush/adm/data_validator.rb +0 -11
- data/lib/rpush/adm/notification.rb +0 -29
- data/lib/rpush/apns/app.rb +0 -29
- data/lib/rpush/apns/binary_notification_validator.rb +0 -12
- data/lib/rpush/apns/device_token_format_validator.rb +0 -12
- data/lib/rpush/apns/feedback.rb +0 -16
- data/lib/rpush/apns/notification.rb +0 -84
- data/lib/rpush/app.rb +0 -18
- data/lib/rpush/daemon/apns/certificate_expired_error.rb +0 -20
- data/lib/rpush/daemon/apns/disconnection_error.rb +0 -20
- data/lib/rpush/gcm/app.rb +0 -11
- data/lib/rpush/gcm/expiry_collapse_key_mutual_inclusion_validator.rb +0 -11
- data/lib/rpush/gcm/notification.rb +0 -30
- data/lib/rpush/notification.rb +0 -69
- data/lib/rpush/notifier.rb +0 -52
- data/lib/rpush/payload_data_size_validator.rb +0 -10
- data/lib/rpush/railtie.rb +0 -11
- data/lib/rpush/registration_ids_count_validator.rb +0 -10
- data/lib/rpush/wpns/app.rb +0 -9
- data/lib/rpush/wpns/notification.rb +0 -26
- data/lib/tasks/cane.rake +0 -18
- data/lib/tasks/rpush.rake +0 -16
- data/spec/unit/apns/app_spec.rb +0 -29
- data/spec/unit/apns/feedback_spec.rb +0 -9
- data/spec/unit/apns/notification_spec.rb +0 -208
- data/spec/unit/app_spec.rb +0 -30
- data/spec/unit/daemon/apns/disconnection_error_spec.rb +0 -18
- data/spec/unit/daemon/interruptible_sleep_spec.rb +0 -68
- data/spec/unit/gcm/app_spec.rb +0 -4
- data/spec/unit/notification_spec.rb +0 -15
- data/spec/unit/notifier_spec.rb +0 -49
- data/spec/unit/wpns/app_spec.rb +0 -4
- data/spec/unit/wpns/notification_spec.rb +0 -30
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
class PGError < StandardError; end
|
|
2
|
-
class Mysql; class Error < StandardError; end; end
|
|
3
|
-
module Mysql2; class Error < StandardError; end; end
|
|
4
|
-
module ActiveRecord
|
|
5
|
-
class
|
|
1
|
+
class PGError < StandardError; end unless defined?(PGError)
|
|
2
|
+
class Mysql; class Error < StandardError; end; end unless defined?(Mysql)
|
|
3
|
+
module Mysql2; class Error < StandardError; end; end unless defined?(Mysql2)
|
|
4
|
+
module ActiveRecord
|
|
5
|
+
class JDBCError < StandardError; end unless defined?(::ActiveRecord::JDBCError)
|
|
6
|
+
end
|
|
6
7
|
|
|
7
8
|
# :nocov:
|
|
8
|
-
|
|
9
|
+
unless defined?(::SQLite3::Exception)
|
|
9
10
|
module SQLite3
|
|
10
11
|
class Exception < StandardError; end
|
|
11
12
|
end
|
|
@@ -20,15 +21,14 @@ module Rpush
|
|
|
20
21
|
Mysql2::Error, ::ActiveRecord::JDBCError, SQLite3::Exception]
|
|
21
22
|
|
|
22
23
|
def with_database_reconnect_and_retry
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
yield
|
|
26
|
-
end
|
|
27
|
-
rescue *ADAPTER_ERRORS => e
|
|
28
|
-
Rpush.logger.error(e)
|
|
29
|
-
database_connection_lost
|
|
30
|
-
retry
|
|
24
|
+
::ActiveRecord::Base.connection_pool.with_connection do
|
|
25
|
+
yield
|
|
31
26
|
end
|
|
27
|
+
rescue *ADAPTER_ERRORS => e
|
|
28
|
+
Rpush.logger.error(e)
|
|
29
|
+
sleep_to_avoid_thrashing
|
|
30
|
+
database_connection_lost
|
|
31
|
+
retry
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
def database_connection_lost
|
|
@@ -55,7 +55,7 @@ module Rpush
|
|
|
55
55
|
|
|
56
56
|
def check_database_is_connected
|
|
57
57
|
# Simply asking the adapter for the connection state is not sufficient.
|
|
58
|
-
Rpush::Notification.count
|
|
58
|
+
Rpush::Client::ActiveRecord::Notification.count
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
def sleep_to_avoid_thrashing
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Rpush
|
|
2
|
+
module Daemon
|
|
3
|
+
module Store
|
|
4
|
+
class Interface
|
|
5
|
+
PUBLIC_METHODS = [:deliverable_notifications, :mark_retryable,
|
|
6
|
+
:mark_batch_retryable, :mark_delivered, :mark_batch_delivered,
|
|
7
|
+
:mark_failed, :mark_batch_failed, :create_apns_feedback,
|
|
8
|
+
:create_gcm_notification, :create_adm_notification, :update_app,
|
|
9
|
+
:update_notification, :release_connection,
|
|
10
|
+
:all_apps, :app, :mark_ids_failed, :mark_ids_retryable]
|
|
11
|
+
|
|
12
|
+
def self.check(klass)
|
|
13
|
+
missing = PUBLIC_METHODS - klass.instance_methods.map(&:to_sym)
|
|
14
|
+
fail "#{klass} must implement #{missing.join(', ')}." if missing.any?
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
module Rpush
|
|
2
|
+
module Daemon
|
|
3
|
+
module Store
|
|
4
|
+
class Redis
|
|
5
|
+
DEFAULT_MARK_OPTIONS = { persist: true }
|
|
6
|
+
|
|
7
|
+
def app(app_id)
|
|
8
|
+
Rpush::Client::Redis::App.find(app_id)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def all_apps
|
|
12
|
+
Rpush::Client::Redis::App.all
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def deliverable_notifications(limit)
|
|
16
|
+
retryable_ids = retryable_notification_ids
|
|
17
|
+
limit -= retryable_ids.size
|
|
18
|
+
pending_ids = limit > 0 ? pending_notification_ids(limit) : []
|
|
19
|
+
ids = retryable_ids + pending_ids
|
|
20
|
+
ids.map { |id| Rpush::Client::Redis::Notification.find(id) }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def mark_delivered(notification, time, opts = {})
|
|
24
|
+
opts = DEFAULT_MARK_OPTIONS.dup.merge(opts)
|
|
25
|
+
notification.delivered = true
|
|
26
|
+
notification.delivered_at = time
|
|
27
|
+
notification.save!(validate: false) if opts[:persist]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def mark_batch_delivered(notifications)
|
|
31
|
+
now = Time.now
|
|
32
|
+
notifications.each { |n| mark_delivered(n, now) }
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def mark_failed(notification, code, description, time, opts = {})
|
|
36
|
+
opts = DEFAULT_MARK_OPTIONS.dup.merge(opts)
|
|
37
|
+
notification.delivered = false
|
|
38
|
+
notification.delivered_at = nil
|
|
39
|
+
notification.failed = true
|
|
40
|
+
notification.failed_at = time
|
|
41
|
+
notification.error_code = code
|
|
42
|
+
notification.error_description = description
|
|
43
|
+
notification.save!(validate: false) if opts[:persist]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def mark_batch_failed(notifications, code, description)
|
|
47
|
+
now = Time.now
|
|
48
|
+
notifications.each { |n| mark_failed(n, code, description, now) }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def mark_ids_failed(ids, code, description, time)
|
|
52
|
+
ids.each { |id| mark_failed(Rpush::Client::Redis::Apns::Notification.find(id), code, description, time) }
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def mark_retryable(notification, deliver_after, opts = {})
|
|
56
|
+
opts = DEFAULT_MARK_OPTIONS.dup.merge(opts)
|
|
57
|
+
notification.delivered = false
|
|
58
|
+
notification.delivered_at = nil
|
|
59
|
+
notification.failed = false
|
|
60
|
+
notification.failed_at = nil
|
|
61
|
+
notification.retries += 1
|
|
62
|
+
notification.deliver_after = deliver_after
|
|
63
|
+
|
|
64
|
+
return unless opts[:persist]
|
|
65
|
+
|
|
66
|
+
notification.save!(validate: false)
|
|
67
|
+
namespace = Rpush::Client::Redis::Notification.absolute_retryable_namespace
|
|
68
|
+
Modis.with_connection do |redis|
|
|
69
|
+
redis.zadd(namespace, deliver_after.to_i, notification.id)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def mark_batch_retryable(notifications, deliver_after)
|
|
74
|
+
notifications.each { |n| mark_retryable(n, deliver_after) }
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def mark_ids_retryable(ids, deliver_after)
|
|
78
|
+
ids.each { |id| mark_retryable(Rpush::Client::Redis::Apns::Notification.find(id), deliver_after) }
|
|
79
|
+
end
|
|
80
|
+
|
|
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, app: app)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def create_gcm_notification(attrs, data, registration_ids, deliver_after, app) # rubocop:disable ParameterLists
|
|
86
|
+
notification = Rpush::Client::Redis::Gcm::Notification.new
|
|
87
|
+
create_gcm_like_notification(notification, attrs, data, registration_ids, deliver_after, app)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def create_adm_notification(attrs, data, registration_ids, deliver_after, app) # rubocop:disable ParameterLists
|
|
91
|
+
notification = Rpush::Client::Redis::Adm::Notification.new
|
|
92
|
+
create_gcm_like_notification(notification, attrs, data, registration_ids, deliver_after, app)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def update_app(app)
|
|
96
|
+
app.save!
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def update_notification(notification)
|
|
100
|
+
notification.save!
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def release_connection
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
private
|
|
107
|
+
|
|
108
|
+
def create_gcm_like_notification(notification, attrs, data, registration_ids, deliver_after, app) # rubocop:disable ParameterLists
|
|
109
|
+
notification.assign_attributes(attrs)
|
|
110
|
+
notification.data = data
|
|
111
|
+
notification.registration_ids = registration_ids
|
|
112
|
+
notification.deliver_after = deliver_after
|
|
113
|
+
notification.app = app
|
|
114
|
+
notification.save!
|
|
115
|
+
notification
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def retryable_notification_ids
|
|
119
|
+
retryable_ns = Rpush::Client::Redis::Notification.absolute_retryable_namespace
|
|
120
|
+
|
|
121
|
+
Modis.with_connection do |redis|
|
|
122
|
+
retryable_results = redis.multi do
|
|
123
|
+
now = Time.now.to_i
|
|
124
|
+
redis.zrangebyscore(retryable_ns, 0, now)
|
|
125
|
+
redis.zremrangebyscore(retryable_ns, 0, now)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
retryable_results.first
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def pending_notification_ids(limit)
|
|
133
|
+
pending_ns = Rpush::Client::Redis::Notification.absolute_pending_namespace
|
|
134
|
+
|
|
135
|
+
Modis.with_connection do |redis|
|
|
136
|
+
pending_results = redis.multi do
|
|
137
|
+
redis.zrange(pending_ns, 0, limit)
|
|
138
|
+
redis.zremrangebyrank(pending_ns, 0, limit)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
pending_results.first
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
Rpush::Daemon::Store::Interface.check(Rpush::Daemon::Store::Redis)
|
|
@@ -27,11 +27,9 @@ module Rpush
|
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
def close
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
rescue IOError
|
|
34
|
-
end
|
|
30
|
+
@ssl_socket.close if @ssl_socket
|
|
31
|
+
@tcp_socket.close if @tcp_socket
|
|
32
|
+
rescue IOError # rubocop:disable HandleExceptions
|
|
35
33
|
end
|
|
36
34
|
|
|
37
35
|
def read(num_bytes)
|
|
@@ -50,11 +48,10 @@ module Rpush
|
|
|
50
48
|
begin
|
|
51
49
|
write_data(data)
|
|
52
50
|
rescue Errno::EPIPE, Errno::ETIMEDOUT, OpenSSL::SSL::SSLError, IOError => e
|
|
53
|
-
retry_count += 1
|
|
51
|
+
retry_count += 1
|
|
54
52
|
|
|
55
53
|
if retry_count == 1
|
|
56
54
|
log_error("Lost connection to #{@host}:#{@port} (#{e.class.name}), reconnecting...")
|
|
57
|
-
reflect(:apns_connection_lost, @app, e) # deprecated
|
|
58
55
|
reflect(:tcp_connection_lost, @app, e)
|
|
59
56
|
end
|
|
60
57
|
|
|
@@ -63,7 +60,7 @@ module Rpush
|
|
|
63
60
|
sleep 1
|
|
64
61
|
retry
|
|
65
62
|
else
|
|
66
|
-
raise TcpConnectionError, "#{@app.name} tried #{retry_count-1} times to reconnect but failed (#{e.class.name})."
|
|
63
|
+
raise TcpConnectionError, "#{@app.name} tried #{retry_count - 1} times to reconnect but failed (#{e.class.name})."
|
|
67
64
|
end
|
|
68
65
|
end
|
|
69
66
|
end
|
|
@@ -110,7 +107,6 @@ module Rpush
|
|
|
110
107
|
ssl_socket = OpenSSL::SSL::SSLSocket.new(tcp_socket, @ssl_context)
|
|
111
108
|
ssl_socket.sync = true
|
|
112
109
|
ssl_socket.connect
|
|
113
|
-
log_info("Connected to #{@host}:#{@port}")
|
|
114
110
|
[tcp_socket, ssl_socket]
|
|
115
111
|
end
|
|
116
112
|
|
|
@@ -118,10 +114,9 @@ module Rpush
|
|
|
118
114
|
cert = @ssl_context.cert
|
|
119
115
|
if certificate_expired?
|
|
120
116
|
log_error(certificate_msg('expired'))
|
|
121
|
-
|
|
117
|
+
fail Rpush::CertificateExpiredError.new(@app, cert.not_after)
|
|
122
118
|
elsif certificate_expires_soon?
|
|
123
119
|
log_warn(certificate_msg('will expire'))
|
|
124
|
-
reflect(:apns_certificate_will_expire, @app, cert.not_after) # deprecated
|
|
125
120
|
reflect(:ssl_certificate_will_expire, @app, cert.not_after)
|
|
126
121
|
end
|
|
127
122
|
end
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
module Rpush
|
|
2
2
|
module Daemon
|
|
3
3
|
module Wpns
|
|
4
|
-
|
|
5
4
|
# http://msdn.microsoft.com/en-us/library/windowsphone/develop/ff941100%28v=vs.105%29.aspx
|
|
6
5
|
class Delivery < Rpush::Daemon::Delivery
|
|
7
|
-
|
|
8
6
|
FAILURE_MESSAGES = {
|
|
9
7
|
400 => 'Bad XML or malformed notification URI.',
|
|
10
8
|
401 => 'Unauthorized to send a notification to this app.'
|
|
@@ -18,12 +16,12 @@ module Rpush
|
|
|
18
16
|
end
|
|
19
17
|
|
|
20
18
|
def perform
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
handle_response(do_post)
|
|
20
|
+
rescue StandardError => error
|
|
21
|
+
mark_failed(error)
|
|
22
|
+
raise
|
|
23
|
+
ensure
|
|
24
|
+
@batch.notification_processed
|
|
27
25
|
end
|
|
28
26
|
|
|
29
27
|
private
|
|
@@ -34,25 +32,21 @@ module Rpush
|
|
|
34
32
|
when 200
|
|
35
33
|
ok(response)
|
|
36
34
|
when 406
|
|
37
|
-
not_acceptable
|
|
35
|
+
not_acceptable
|
|
38
36
|
when 412
|
|
39
|
-
precondition_failed
|
|
37
|
+
precondition_failed
|
|
40
38
|
when 503
|
|
41
|
-
service_unavailable
|
|
39
|
+
service_unavailable
|
|
42
40
|
else
|
|
43
41
|
handle_failure(code)
|
|
44
42
|
end
|
|
45
43
|
end
|
|
46
44
|
|
|
47
|
-
def handle_failure(code, msg=nil)
|
|
45
|
+
def handle_failure(code, msg = nil)
|
|
48
46
|
unless msg
|
|
49
|
-
msg =
|
|
50
|
-
FAILURE_MESSAGES[code]
|
|
51
|
-
else
|
|
52
|
-
Rpush::Daemon::HTTP_STATUS_CODES[code]
|
|
53
|
-
end
|
|
47
|
+
msg = FAILURE_MESSAGES.key?(code) ? FAILURE_MESSAGES[code] : Rpush::Daemon::HTTP_STATUS_CODES[code]
|
|
54
48
|
end
|
|
55
|
-
|
|
49
|
+
fail Rpush::DeliveryError.new(code, @notification.id, msg)
|
|
56
50
|
end
|
|
57
51
|
|
|
58
52
|
def ok(response)
|
|
@@ -62,22 +56,22 @@ module Rpush
|
|
|
62
56
|
mark_delivered
|
|
63
57
|
log_info("#{@notification.id} sent successfully")
|
|
64
58
|
when ["QueueFull"]
|
|
65
|
-
mark_retryable(@notification, Time.now + (60*10))
|
|
59
|
+
mark_retryable(@notification, Time.now + (60 * 10))
|
|
66
60
|
log_warn("#{@notification.id} cannot be sent. The Queue is full.")
|
|
67
61
|
when ["Suppressed"]
|
|
68
62
|
handle_failure(200, "Notification was received but suppressed by the service.")
|
|
69
63
|
end
|
|
70
64
|
end
|
|
71
65
|
|
|
72
|
-
def not_acceptable
|
|
66
|
+
def not_acceptable
|
|
73
67
|
retry_notification("Per-day throttling limit reached.")
|
|
74
68
|
end
|
|
75
69
|
|
|
76
|
-
def precondition_failed
|
|
70
|
+
def precondition_failed
|
|
77
71
|
retry_notification("Device unreachable.")
|
|
78
72
|
end
|
|
79
73
|
|
|
80
|
-
def service_unavailable
|
|
74
|
+
def service_unavailable
|
|
81
75
|
mark_retryable_exponential(@notification)
|
|
82
76
|
log_warn("Service Unavailable. " + retry_message)
|
|
83
77
|
end
|
|
@@ -87,20 +81,17 @@ module Rpush
|
|
|
87
81
|
end
|
|
88
82
|
|
|
89
83
|
def retry_notification(reason)
|
|
90
|
-
deliver_after = Time.now + (60*60)
|
|
84
|
+
deliver_after = Time.now + (60 * 60)
|
|
91
85
|
mark_retryable(@notification, deliver_after)
|
|
92
86
|
log_warn("#{reason} " + retry_message)
|
|
93
87
|
end
|
|
94
88
|
|
|
95
89
|
def do_post
|
|
96
90
|
body = notification_to_xml
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
"X-NotificationClass" => '2'
|
|
102
|
-
}
|
|
103
|
-
post = Net::HTTP::Post.new(URI.parse(@notification.uri).path, initheader=header)
|
|
91
|
+
post = Net::HTTP::Post.new(URI.parse(@notification.uri).path, "Content-Length" => body.length.to_s,
|
|
92
|
+
"Content-Type" => "text/xml",
|
|
93
|
+
"X-WindowsPhone-Target" => "toast",
|
|
94
|
+
"X-NotificationClass" => '2')
|
|
104
95
|
post.body = body
|
|
105
96
|
@http.request(URI.parse(@notification.uri), post)
|
|
106
97
|
end
|
data/lib/rpush/deprecatable.rb
CHANGED
|
@@ -5,16 +5,17 @@ module Rpush
|
|
|
5
5
|
end
|
|
6
6
|
|
|
7
7
|
module ClassMethods
|
|
8
|
-
def deprecated(method_name, version, msg=nil)
|
|
8
|
+
def deprecated(method_name, version, msg = nil)
|
|
9
|
+
method_name_as_var = method_name.to_s.tr('=', '_setter_')
|
|
9
10
|
instance_eval do
|
|
10
|
-
alias_method "#{
|
|
11
|
+
alias_method "#{method_name_as_var}_without_warning", method_name
|
|
11
12
|
end
|
|
12
13
|
warning = "#{method_name} is deprecated and will be removed from Rpush #{version}."
|
|
13
14
|
warning << " #{msg}" if msg
|
|
14
15
|
class_eval(<<-RUBY, __FILE__, __LINE__)
|
|
15
16
|
def #{method_name}(*args, &blk)
|
|
16
17
|
Rpush::Deprecation.warn(#{warning.inspect})
|
|
17
|
-
#{
|
|
18
|
+
#{method_name_as_var}_without_warning(*args, &blk)
|
|
18
19
|
end
|
|
19
20
|
RUBY
|
|
20
21
|
end
|
data/lib/rpush/deprecation.rb
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
module Rpush
|
|
2
2
|
class Deprecation
|
|
3
3
|
def self.muted
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Thread.current[:rpush_mute_deprecations] = orig_val
|
|
10
|
-
end
|
|
4
|
+
orig_val = Thread.current[:rpush_mute_deprecations]
|
|
5
|
+
Thread.current[:rpush_mute_deprecations] = true
|
|
6
|
+
yield
|
|
7
|
+
ensure
|
|
8
|
+
Thread.current[:rpush_mute_deprecations] = orig_val
|
|
11
9
|
end
|
|
12
10
|
|
|
13
11
|
def self.muted?
|
|
@@ -15,9 +13,8 @@ module Rpush
|
|
|
15
13
|
end
|
|
16
14
|
|
|
17
15
|
def self.warn(msg)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
end
|
|
16
|
+
return if Rpush::Deprecation.muted?
|
|
17
|
+
STDERR.puts "DEPRECATION WARNING: #{msg}"
|
|
21
18
|
end
|
|
22
19
|
end
|
|
23
20
|
end
|
data/lib/rpush/embed.rb
CHANGED
|
@@ -2,18 +2,23 @@ module Rpush
|
|
|
2
2
|
def self.embed(options = {})
|
|
3
3
|
Rpush.require_for_daemon
|
|
4
4
|
|
|
5
|
+
if @embed_thread
|
|
6
|
+
STDERR.puts 'Rpush.embed can only be run once inside this process.'
|
|
7
|
+
end
|
|
8
|
+
|
|
5
9
|
config = Rpush::ConfigurationWithoutDefaults.new
|
|
6
10
|
options.each { |k, v| config.send("#{k}=", v) }
|
|
7
11
|
config.embedded = true
|
|
8
12
|
Rpush.config.update(config)
|
|
9
|
-
Rpush::Daemon.start
|
|
10
|
-
|
|
11
13
|
Kernel.at_exit { shutdown }
|
|
14
|
+
@embed_thread = Thread.new { Rpush::Daemon.start }
|
|
12
15
|
end
|
|
13
16
|
|
|
14
17
|
def self.shutdown
|
|
15
18
|
return unless Rpush.config.embedded
|
|
16
19
|
Rpush::Daemon.shutdown
|
|
20
|
+
@embed_thread.join if @embed_thread
|
|
21
|
+
@embed_thread = nil
|
|
17
22
|
end
|
|
18
23
|
|
|
19
24
|
def self.sync
|