rpush 2.4.0-java → 2.6.0-java
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 +27 -1
- data/README.md +18 -8
- data/lib/generators/rpush_migration_generator.rb +1 -0
- data/lib/generators/templates/rpush.rb +8 -2
- data/lib/generators/templates/rpush_2_0_0_updates.rb +1 -1
- data/lib/generators/templates/rpush_2_6_0_updates.rb +10 -0
- data/lib/rpush/cli.rb +63 -27
- data/lib/rpush/client/active_model.rb +3 -0
- data/lib/rpush/client/active_model/apns/notification.rb +1 -1
- data/lib/rpush/client/active_model/gcm/notification.rb +1 -0
- data/lib/rpush/client/active_model/wns/app.rb +23 -0
- data/lib/rpush/client/active_model/wns/notification.rb +28 -0
- data/lib/rpush/client/active_model/wpns/notification.rb +11 -6
- data/lib/rpush/client/active_record.rb +3 -0
- data/lib/rpush/client/active_record/notification.rb +1 -1
- data/lib/rpush/client/active_record/wns/app.rb +11 -0
- data/lib/rpush/client/active_record/wns/notification.rb +11 -0
- data/lib/rpush/client/mongoid.rb +3 -0
- data/lib/rpush/client/mongoid/apns/feedback.rb +3 -0
- data/lib/rpush/client/mongoid/notification.rb +7 -0
- data/lib/rpush/client/mongoid/wns/app.rb +14 -0
- data/lib/rpush/client/mongoid/wns/notification.rb +11 -0
- data/lib/rpush/client/redis.rb +3 -0
- data/lib/rpush/client/redis/notification.rb +1 -0
- data/lib/rpush/client/redis/wns/app.rb +14 -0
- data/lib/rpush/client/redis/wns/notification.rb +11 -0
- data/lib/rpush/configuration.rb +3 -7
- data/lib/rpush/daemon.rb +9 -0
- data/lib/rpush/daemon/apns/feedback_receiver.rb +5 -0
- data/lib/rpush/daemon/app_runner.rb +4 -5
- data/lib/rpush/daemon/dispatcher/apns_tcp.rb +47 -12
- data/lib/rpush/daemon/dispatcher_loop.rb +5 -0
- data/lib/rpush/daemon/feeder.rb +11 -0
- data/lib/rpush/daemon/gcm/delivery.rb +2 -2
- data/lib/rpush/daemon/interruptible_sleep.rb +8 -3
- data/lib/rpush/daemon/loggable.rb +4 -0
- data/lib/rpush/daemon/rpc.rb +9 -0
- data/lib/rpush/daemon/rpc/client.rb +27 -0
- data/lib/rpush/daemon/rpc/server.rb +82 -0
- data/lib/rpush/daemon/signal_handler.rb +7 -0
- data/lib/rpush/daemon/store/active_record.rb +17 -3
- data/lib/rpush/daemon/store/mongoid.rb +2 -2
- data/lib/rpush/daemon/store/redis.rb +2 -2
- data/lib/rpush/daemon/tcp_connection.rb +2 -2
- data/lib/rpush/daemon/wns.rb +9 -0
- data/lib/rpush/daemon/wns/delivery.rb +204 -0
- data/lib/rpush/embed.rb +15 -13
- data/lib/rpush/logger.rb +4 -0
- data/lib/rpush/plugin.rb +1 -1
- data/lib/rpush/push.rb +2 -11
- data/lib/rpush/reflection_collection.rb +15 -17
- data/lib/rpush/reflection_public_methods.rb +6 -4
- data/lib/rpush/version.rb +1 -1
- data/spec/functional/apns_spec.rb +1 -11
- data/spec/functional/cli_spec.rb +36 -0
- data/spec/functional_spec_helper.rb +11 -1
- data/spec/spec_helper.rb +4 -3
- data/spec/support/active_record_setup.rb +3 -2
- data/spec/unit/client/active_record/apns/notification_spec.rb +1 -1
- data/spec/unit/client/active_record/gcm/notification_spec.rb +5 -0
- data/spec/unit/configuration_spec.rb +0 -7
- data/spec/unit/daemon/adm/delivery_spec.rb +2 -2
- data/spec/unit/daemon/app_runner_spec.rb +2 -3
- data/spec/unit/daemon/gcm/delivery_spec.rb +1 -1
- data/spec/unit/daemon/tcp_connection_spec.rb +1 -1
- data/spec/unit/daemon/wns/delivery_spec.rb +171 -0
- data/spec/unit/daemon/wpns/delivery_spec.rb +1 -1
- data/spec/unit/daemon_spec.rb +2 -0
- data/spec/unit/embed_spec.rb +4 -11
- data/spec/unit/logger_spec.rb +2 -2
- data/spec/unit/push_spec.rb +0 -7
- data/spec/unit_spec_helper.rb +1 -1
- metadata +20 -2
data/lib/rpush/client/mongoid.rb
CHANGED
@@ -27,5 +27,8 @@ require 'rpush/client/mongoid/gcm/app'
|
|
27
27
|
require 'rpush/client/mongoid/wpns/notification'
|
28
28
|
require 'rpush/client/mongoid/wpns/app'
|
29
29
|
|
30
|
+
require 'rpush/client/mongoid/wns/notification'
|
31
|
+
require 'rpush/client/mongoid/wns/app'
|
32
|
+
|
30
33
|
require 'rpush/client/mongoid/adm/notification'
|
31
34
|
require 'rpush/client/mongoid/adm/app'
|
@@ -3,6 +3,7 @@ module Rpush
|
|
3
3
|
module Mongoid
|
4
4
|
class Notification
|
5
5
|
include ::Mongoid::Document
|
6
|
+
include ::Mongoid::Timestamps
|
6
7
|
include ::Mongoid::Autoinc
|
7
8
|
include Rpush::MultiJsonHelper
|
8
9
|
include Rpush::Client::ActiveModel::Notification
|
@@ -31,11 +32,17 @@ module Rpush
|
|
31
32
|
field :priority, type: Integer
|
32
33
|
field :url_args, type: Array
|
33
34
|
field :category, type: String
|
35
|
+
field :content_available, type: Boolean, default: false
|
34
36
|
|
35
37
|
field :integer_id, type: Integer
|
36
38
|
increments :integer_id, model_name: name
|
37
39
|
index integer_id: 1
|
38
40
|
|
41
|
+
index delivered: 1, failed: 1, deliver_after: 1, processing: 1
|
42
|
+
index delivered: 1, failed: 1
|
43
|
+
index device_token: 1
|
44
|
+
index app_id: 1
|
45
|
+
|
39
46
|
belongs_to :app
|
40
47
|
end
|
41
48
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Rpush
|
2
|
+
module Client
|
3
|
+
module Mongoid
|
4
|
+
module Wns
|
5
|
+
class App < Rpush::Client::Mongoid::App
|
6
|
+
include Rpush::Client::ActiveModel::Wns::App
|
7
|
+
|
8
|
+
field :access_token, type: String
|
9
|
+
field :access_token_expiration, type: Time
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/rpush/client/redis.rb
CHANGED
@@ -30,6 +30,9 @@ require 'rpush/client/redis/adm/notification'
|
|
30
30
|
require 'rpush/client/redis/wpns/app'
|
31
31
|
require 'rpush/client/redis/wpns/notification'
|
32
32
|
|
33
|
+
require 'rpush/client/redis/wns/app'
|
34
|
+
require 'rpush/client/redis/wns/notification'
|
35
|
+
|
33
36
|
Modis.configure do |config|
|
34
37
|
config.namespace = :rpush
|
35
38
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Rpush
|
2
|
+
module Client
|
3
|
+
module Redis
|
4
|
+
module Wns
|
5
|
+
class App < Rpush::Client::Redis::App
|
6
|
+
include Rpush::Client::ActiveModel::Wns::App
|
7
|
+
|
8
|
+
attribute :access_token, :string
|
9
|
+
attribute :access_token_expiration, :timestamp
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/rpush/configuration.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'pathname'
|
2
|
+
require 'ostruct'
|
2
3
|
|
3
4
|
module Rpush
|
4
5
|
class << self
|
@@ -16,7 +17,7 @@ module Rpush
|
|
16
17
|
end
|
17
18
|
|
18
19
|
CURRENT_ATTRS = [:push_poll, :embedded, :pid_file, :batch_size, :push, :client, :logger, :log_file, :foreground, :log_level, :plugin, :apns]
|
19
|
-
DEPRECATED_ATTRS = [
|
20
|
+
DEPRECATED_ATTRS = []
|
20
21
|
CONFIG_ATTRS = CURRENT_ATTRS + DEPRECATED_ATTRS
|
21
22
|
|
22
23
|
class ConfigurationError < StandardError; end
|
@@ -97,11 +98,6 @@ module Rpush
|
|
97
98
|
Modis.redis_options = options if client == :redis
|
98
99
|
end
|
99
100
|
|
100
|
-
def feedback_poll=(frequency)
|
101
|
-
apns.feedback_receiver.frequency = frequency
|
102
|
-
end
|
103
|
-
deprecated(:feedback_poll=, '2.5.0', 'Please use apns.feedback_receiver.frequency= instead.')
|
104
|
-
|
105
101
|
def initialize_client
|
106
102
|
return if @client_initialized
|
107
103
|
raise ConfigurationError, 'Rpush.config.client is not set.' unless client
|
@@ -110,7 +106,7 @@ module Rpush
|
|
110
106
|
client_module = Rpush::Client.const_get(client.to_s.camelize)
|
111
107
|
Rpush.send(:include, client_module) unless Rpush.ancestors.include?(client_module)
|
112
108
|
|
113
|
-
[:Apns, :Gcm, :Wpns, :Adm].each do |service|
|
109
|
+
[:Apns, :Gcm, :Wpns, :Wns, :Adm].each do |service|
|
114
110
|
Rpush.const_set(service, client_module.const_get(service)) unless Rpush.const_defined?(service)
|
115
111
|
end
|
116
112
|
|
data/lib/rpush/daemon.rb
CHANGED
@@ -30,6 +30,10 @@ require 'rpush/daemon/ring_buffer'
|
|
30
30
|
require 'rpush/daemon/signal_handler'
|
31
31
|
require 'rpush/daemon/proc_title'
|
32
32
|
|
33
|
+
require 'rpush/daemon/rpc'
|
34
|
+
require 'rpush/daemon/rpc/server'
|
35
|
+
require 'rpush/daemon/rpc/client'
|
36
|
+
|
33
37
|
require 'rpush/daemon/store/interface'
|
34
38
|
|
35
39
|
require 'rpush/daemon/apns/delivery'
|
@@ -42,6 +46,9 @@ require 'rpush/daemon/gcm'
|
|
42
46
|
require 'rpush/daemon/wpns/delivery'
|
43
47
|
require 'rpush/daemon/wpns'
|
44
48
|
|
49
|
+
require 'rpush/daemon/wns/delivery'
|
50
|
+
require 'rpush/daemon/wns'
|
51
|
+
|
45
52
|
require 'rpush/daemon/adm/delivery'
|
46
53
|
require 'rpush/daemon/adm'
|
47
54
|
|
@@ -57,6 +64,7 @@ module Rpush
|
|
57
64
|
SignalHandler.start
|
58
65
|
common_init
|
59
66
|
Synchronizer.sync
|
67
|
+
Rpc::Server.start
|
60
68
|
|
61
69
|
# No further store connections will be made from this thread.
|
62
70
|
store.release_connection
|
@@ -81,6 +89,7 @@ module Rpush
|
|
81
89
|
Rpush.logger.info('Shutting down... ', true)
|
82
90
|
|
83
91
|
shutdown_lock.synchronize do
|
92
|
+
Rpc::Server.stop
|
84
93
|
Feeder.stop
|
85
94
|
AppRunner.stop
|
86
95
|
delete_pid_file
|
@@ -84,8 +84,8 @@ module Rpush
|
|
84
84
|
@runners[app.id].increment_dispatchers(num)
|
85
85
|
end
|
86
86
|
|
87
|
-
def self.
|
88
|
-
@runners.values.map(&:
|
87
|
+
def self.status
|
88
|
+
{ app_runners: @runners.values.map(&:status) }
|
89
89
|
end
|
90
90
|
|
91
91
|
attr_reader :app
|
@@ -140,7 +140,7 @@ module Rpush
|
|
140
140
|
num.times { @dispatcher_loops.push(new_dispatcher_loop) }
|
141
141
|
end
|
142
142
|
|
143
|
-
def
|
143
|
+
def status
|
144
144
|
dispatcher_details = {}
|
145
145
|
|
146
146
|
@dispatcher_loops.each_with_index do |dispatcher_loop, i|
|
@@ -151,8 +151,7 @@ module Rpush
|
|
151
151
|
}
|
152
152
|
end
|
153
153
|
|
154
|
-
|
155
|
-
log_info(JSON.pretty_generate(runner_details))
|
154
|
+
{ app_name: @app.name, dispatchers: dispatcher_details, queued: queue_size }
|
156
155
|
end
|
157
156
|
|
158
157
|
def num_dispatcher_loops
|
@@ -16,6 +16,7 @@ module Rpush
|
|
16
16
|
6 => 'Missing topic size',
|
17
17
|
7 => 'Missing payload size',
|
18
18
|
8 => 'Invalid token',
|
19
|
+
10 => 'APNs closed connection (possible maintenance)',
|
19
20
|
255 => 'None (unknown error)'
|
20
21
|
}
|
21
22
|
|
@@ -34,9 +35,21 @@ module Rpush
|
|
34
35
|
end
|
35
36
|
|
36
37
|
def cleanup
|
38
|
+
if Rpush.config.push
|
39
|
+
# In push mode only a single batch is sent, followed my immediate shutdown.
|
40
|
+
# Allow the error receiver time to handle any errors.
|
41
|
+
@reconnect_disabled = true
|
42
|
+
sleep 1
|
43
|
+
end
|
44
|
+
|
37
45
|
@stop_error_receiver = true
|
38
46
|
super
|
39
47
|
@error_receiver_thread.join if @error_receiver_thread
|
48
|
+
rescue StandardError => e
|
49
|
+
log_error(e)
|
50
|
+
reflect(:error, e)
|
51
|
+
ensure
|
52
|
+
@error_receiver_thread = nil
|
40
53
|
end
|
41
54
|
|
42
55
|
private
|
@@ -63,12 +76,12 @@ module Rpush
|
|
63
76
|
# On Linux, select returns nil from a dropped connection.
|
64
77
|
# On OS X, Errno::EBADF is raised following a Errno::EADDRNOTAVAIL from the write call.
|
65
78
|
return unless @connection.select(SELECT_TIMEOUT)
|
66
|
-
|
67
|
-
|
79
|
+
tuple = @connection.read(ERROR_TUPLE_BYTES)
|
80
|
+
rescue *TcpConnection::TCP_ERRORS
|
81
|
+
reconnect unless @stop_error_receiver
|
68
82
|
return
|
69
83
|
end
|
70
84
|
|
71
|
-
tuple = @connection.read(ERROR_TUPLE_BYTES)
|
72
85
|
@dispatch_mutex.synchronize { handle_error_response(tuple) }
|
73
86
|
rescue StandardError => e
|
74
87
|
log_error(e)
|
@@ -82,12 +95,23 @@ module Rpush
|
|
82
95
|
handle_disconnect
|
83
96
|
end
|
84
97
|
|
85
|
-
|
86
|
-
|
98
|
+
if Rpush.config.push
|
99
|
+
# Only attempt to handle a single error in Push mode.
|
100
|
+
@stop_error_receiver = true
|
101
|
+
return
|
102
|
+
end
|
103
|
+
|
104
|
+
reconnect
|
87
105
|
ensure
|
88
106
|
delivered_buffer.clear
|
89
107
|
end
|
90
108
|
|
109
|
+
def reconnect
|
110
|
+
return if @reconnect_disabled
|
111
|
+
log_error("Lost connection to #{@connection.host}:#{@connection.port}, reconnecting...")
|
112
|
+
@connection.reconnect_with_rescue
|
113
|
+
end
|
114
|
+
|
91
115
|
def handle_disconnect
|
92
116
|
log_error("The APNs disconnected before any notifications could be delivered. This usually indicates you are using an invalid certificate.") if delivered_buffer.size == 0
|
93
117
|
end
|
@@ -95,22 +119,33 @@ module Rpush
|
|
95
119
|
def handle_error(code, notification_id)
|
96
120
|
notification_id = Rpush::Daemon.store.translate_integer_notification_id(notification_id)
|
97
121
|
failed_pos = delivered_buffer.index(notification_id)
|
98
|
-
description =
|
99
|
-
log_error(
|
122
|
+
description = description_for_code(code)
|
123
|
+
log_error("Notification #{notification_id} failed with error: " + description)
|
100
124
|
Rpush::Daemon.store.mark_ids_failed([notification_id], code, description, Time.now)
|
101
125
|
reflect(:notification_id_failed, @app, notification_id, code, description)
|
102
126
|
|
103
127
|
if failed_pos
|
104
128
|
retry_ids = delivered_buffer[(failed_pos + 1)..-1]
|
105
|
-
|
106
|
-
now = Time.now
|
107
|
-
Rpush::Daemon.store.mark_ids_retryable(retry_ids, now)
|
108
|
-
retry_ids.each { |id| reflect(:notification_id_will_retry, @app, id, now) }
|
109
|
-
end
|
129
|
+
retry_notification_ids(retry_ids, notification_id)
|
110
130
|
elsif delivered_buffer.size > 0
|
111
131
|
log_error("Delivery sequence unknown for notifications following #{notification_id}.")
|
112
132
|
end
|
113
133
|
end
|
134
|
+
|
135
|
+
def description_for_code(code)
|
136
|
+
APNS_ERRORS[code.to_i] ? "#{APNS_ERRORS[code.to_i]} (#{code})" : "Unknown error code #{code.inspect}. Possible Rpush bug?"
|
137
|
+
end
|
138
|
+
|
139
|
+
def retry_notification_ids(ids, notification_id)
|
140
|
+
return if ids.size == 0
|
141
|
+
|
142
|
+
now = Time.now
|
143
|
+
Rpush::Daemon.store.mark_ids_retryable(ids, now)
|
144
|
+
notifications_str = 'Notification'
|
145
|
+
notifications_str += 's' if ids.size > 1
|
146
|
+
log_warn("#{notifications_str} #{ids.join(', ')} will be retried due to the failure of notification #{notification_id}.")
|
147
|
+
ids.each { |id| reflect(:notification_id_will_retry, @app, id, now) }
|
148
|
+
end
|
114
149
|
end
|
115
150
|
end
|
116
151
|
end
|
data/lib/rpush/daemon/feeder.rb
CHANGED
@@ -2,6 +2,7 @@ module Rpush
|
|
2
2
|
module Daemon
|
3
3
|
class Feeder
|
4
4
|
extend Reflectable
|
5
|
+
extend Loggable
|
5
6
|
|
6
7
|
def self.start(push_mode = false)
|
7
8
|
self.should_stop = false
|
@@ -12,12 +13,22 @@ module Rpush
|
|
12
13
|
end
|
13
14
|
|
14
15
|
@thread.join
|
16
|
+
rescue StandardError => e
|
17
|
+
log_error(e)
|
18
|
+
reflect(:error, e)
|
19
|
+
ensure
|
20
|
+
@thread = nil
|
15
21
|
end
|
16
22
|
|
17
23
|
def self.stop
|
18
24
|
self.should_stop = true
|
19
25
|
interruptible_sleeper.stop
|
20
26
|
@thread.join if @thread
|
27
|
+
rescue StandardError => e
|
28
|
+
log_error(e)
|
29
|
+
reflect(:error, e)
|
30
|
+
ensure
|
31
|
+
@thread = nil
|
21
32
|
end
|
22
33
|
|
23
34
|
def self.wakeup
|
@@ -5,7 +5,7 @@ module Rpush
|
|
5
5
|
class Delivery < Rpush::Daemon::Delivery
|
6
6
|
include MultiJsonHelper
|
7
7
|
|
8
|
-
host = 'https://
|
8
|
+
host = 'https://gcm-http.googleapis.com'
|
9
9
|
GCM_URI = URI.parse("#{host}/gcm/send")
|
10
10
|
UNAVAILABLE_STATES = %w(Unavailable InternalServerError)
|
11
11
|
INVALID_REGISTRATION_ID_STATES = %w(InvalidRegistration MismatchSenderId NotRegistered InvalidPackageName)
|
@@ -44,7 +44,7 @@ module Rpush
|
|
44
44
|
when 503
|
45
45
|
service_unavailable(response)
|
46
46
|
else
|
47
|
-
fail Rpush::DeliveryError.new(response.code, @notification.id, Rpush::Daemon::HTTP_STATUS_CODES[response.code.to_i])
|
47
|
+
fail Rpush::DeliveryError.new(response.code.to_i, @notification.id, Rpush::Daemon::HTTP_STATUS_CODES[response.code.to_i])
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
@@ -1,17 +1,22 @@
|
|
1
|
-
require 'monitor'
|
2
|
-
|
3
1
|
module Rpush
|
4
2
|
module Daemon
|
5
3
|
class InterruptibleSleep
|
6
4
|
def sleep(duration)
|
7
5
|
@thread = Thread.new { Kernel.sleep duration }
|
8
6
|
Thread.pass
|
9
|
-
|
7
|
+
|
8
|
+
begin
|
9
|
+
@thread.join
|
10
|
+
rescue StandardError
|
11
|
+
@thread = nil
|
12
|
+
end
|
10
13
|
end
|
11
14
|
|
12
15
|
def stop
|
13
16
|
@thread.kill if @thread
|
14
17
|
rescue StandardError # rubocop:disable Lint/HandleExceptions
|
18
|
+
ensure
|
19
|
+
@thread = nil
|
15
20
|
end
|
16
21
|
end
|
17
22
|
end
|