rapns 3.1.0 → 3.2.0
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.
- data/CHANGELOG.md +6 -0
- data/README.md +26 -20
- data/config/database.yml +9 -0
- data/lib/generators/templates/add_gcm.rb +12 -12
- data/lib/rapns/apns/app.rb +2 -2
- data/lib/rapns/apns_feedback.rb +12 -0
- data/lib/rapns/daemon/apns/app_runner.rb +6 -17
- data/lib/rapns/daemon/apns/connection.rb +3 -3
- data/lib/rapns/daemon/apns/delivery.rb +2 -2
- data/lib/rapns/daemon/apns/delivery_handler.rb +19 -5
- data/lib/rapns/daemon/apns/feedback_receiver.rb +10 -6
- data/lib/rapns/daemon/app_runner.rb +14 -8
- data/lib/rapns/daemon/database_reconnectable.rb +6 -6
- data/lib/rapns/daemon/delivery_handler.rb +1 -1
- data/lib/rapns/daemon/feeder.rb +1 -1
- data/lib/rapns/daemon/gcm/delivery.rb +4 -4
- data/lib/rapns/daemon/interruptible_sleep.rb +2 -2
- data/lib/rapns/daemon/reflectable.rb +1 -1
- data/lib/rapns/daemon.rb +4 -40
- data/lib/rapns/logger.rb +66 -0
- data/lib/rapns/push.rb +6 -2
- data/lib/rapns/upgraded.rb +31 -0
- data/lib/rapns/version.rb +1 -1
- data/lib/rapns.rb +12 -0
- data/spec/acceptance_spec_helper.rb +2 -2
- data/spec/unit/apns/feedback_spec.rb +0 -3
- data/spec/unit/apns/notification_spec.rb +0 -3
- data/spec/unit/apns_feedback_spec.rb +16 -0
- data/spec/unit/app_spec.rb +1 -3
- data/spec/unit/daemon/apns/app_runner_spec.rb +9 -5
- data/spec/unit/daemon/apns/connection_spec.rb +2 -2
- data/spec/unit/daemon/apns/delivery_handler_spec.rb +14 -9
- data/spec/unit/daemon/apns/delivery_spec.rb +2 -3
- data/spec/unit/daemon/apns/feedback_receiver_spec.rb +6 -6
- data/spec/unit/daemon/app_runner_spec.rb +26 -6
- data/spec/unit/daemon/database_reconnectable_spec.rb +9 -7
- data/spec/unit/daemon/delivery_handler_shared.rb +3 -3
- data/spec/unit/daemon/feeder_spec.rb +2 -1
- data/spec/unit/daemon/gcm/app_runner_spec.rb +1 -1
- data/spec/unit/daemon/gcm/delivery_spec.rb +7 -7
- data/spec/unit/daemon/reflectable_spec.rb +2 -2
- data/spec/unit/daemon_spec.rb +25 -75
- data/spec/unit/embed_spec.rb +6 -0
- data/spec/unit/gcm/app_spec.rb +1 -2
- data/spec/unit/gcm/notification_spec.rb +0 -2
- data/spec/unit/{daemon/logger_spec.rb → logger_spec.rb} +19 -20
- data/spec/unit/notification_spec.rb +1 -3
- data/spec/unit/push_spec.rb +20 -9
- data/spec/unit/rapns_spec.rb +9 -0
- data/spec/unit/upgraded_spec.rb +46 -0
- data/spec/unit_spec_helper.rb +5 -2
- metadata +20 -6
- data/lib/rapns/daemon/logger.rb +0 -68
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
## 3.2.0 (Apr 1, 2013)
|
2
|
+
* Rapns.apns_feedback for one time feedback retrieval. Rapns.push no longer checks for feedback (#117, #105).
|
3
|
+
* Lazily connect to the APNs only when a notification is to be delivered (#111).
|
4
|
+
* Ensure all notifications are sent when using Rapns.push (#107).
|
5
|
+
* Fix issue with running Rapns.push more than once in the same process (#106).
|
6
|
+
|
1
7
|
## 3.1.0 (Jan 26, 2013)
|
2
8
|
* Rapns.reflect API for fine-grained introspection.
|
3
9
|
* Rapns.embed API for embedding Rapns into an existing process.
|
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
[](http://travis-ci.org/ileitch/rapns)
|
2
|
+
[](https://codeclimate.com/github/ileitch/rapns)
|
2
3
|
|
3
4
|
### Rapns - Professional grade APNs and GCM for Ruby.
|
4
5
|
|
@@ -8,13 +9,13 @@
|
|
8
9
|
* Designed for uptime - signal -HUP to add, update apps.
|
9
10
|
* Stable - reconnects database and network connections when lost.
|
10
11
|
* Run as a daemon or inside an existing process.
|
11
|
-
* Use in a scheduler for low-workload deployments ([Push API](rapns/wiki/Push-API)).
|
12
|
-
* Reflection API for fine-grained instrumentation ([Reflection API](rapns/wiki/Relfection-API)).
|
12
|
+
* Use in a scheduler for low-workload deployments ([Push API](https://github.com/ileitch/rapns/wiki/Push-API)).
|
13
|
+
* Reflection API for fine-grained instrumentation ([Reflection API](https://github.com/ileitch/rapns/wiki/Relfection-API)).
|
13
14
|
* Works with MRI, JRuby, Rubinius 1.8 and 1.9.
|
14
15
|
* [Airbrake](http://airbrakeapp.com/) integration.
|
15
|
-
* Built with
|
16
|
+
* Built with love.
|
16
17
|
|
17
|
-
#### 2.x users please read [upgrading from 2.x to 3.0](rapns/wiki/Upgrading-from-version-2.x-to-3.0)
|
18
|
+
#### 2.x users please read [upgrading from 2.x to 3.0](https://github.com/ileitch/rapns/wiki/Upgrading-from-version-2.x-to-3.0)
|
18
19
|
|
19
20
|
### Who uses Rapns?
|
20
21
|
|
@@ -40,7 +41,7 @@ Generate the migrations, rapns.yml and migrate:
|
|
40
41
|
3. Select both the certificate and private key.
|
41
42
|
4. Right click and select `Export 2 items...`.
|
42
43
|
5. Save the file as `cert.p12`, make sure the File Format is `Personal Information Exchange (p12)`.
|
43
|
-
6. Convert the certificate to a .pem, where `<environment>` should be `
|
44
|
+
6. Convert the certificate to a .pem, where `<environment>` should be `sandbox` or `production`, depending on the certificate you exported.
|
44
45
|
|
45
46
|
Without a password:
|
46
47
|
|
@@ -56,8 +57,8 @@ With a password:
|
|
56
57
|
```ruby
|
57
58
|
app = Rapns::Apns::App.new
|
58
59
|
app.name = "ios_app"
|
59
|
-
app.certificate = File.read("/path/to/
|
60
|
-
app.environment = "
|
60
|
+
app.certificate = File.read("/path/to/sandbox.pem")
|
61
|
+
app.environment = "sandbox"
|
61
62
|
app.password = "certificate password"
|
62
63
|
app.connections = 1
|
63
64
|
app.save!
|
@@ -100,13 +101,17 @@ As a daemon:
|
|
100
101
|
cd /path/to/rails/app
|
101
102
|
rapns <Rails environment> [options]
|
102
103
|
|
103
|
-
Inside an existing process:
|
104
|
+
Inside an existing process (see [Embedding API](https://github.com/ileitch/rapns/wiki/Embedding-API)):
|
104
105
|
|
105
106
|
Rapns.embed
|
106
107
|
|
107
108
|
*Please note that only ever a single instance of Rapns should be running.*
|
108
109
|
|
109
|
-
|
110
|
+
In a scheduler:
|
111
|
+
|
112
|
+
Rapns.push
|
113
|
+
|
114
|
+
See [Configuration](https://github.com/ileitch/rapns/wiki/Configuration) for a list of options, or run `rapns --help`.
|
110
115
|
|
111
116
|
## Updating Rapns
|
112
117
|
|
@@ -115,19 +120,20 @@ After updating you should run `rails g rapns` to check for any new migrations.
|
|
115
120
|
## Wiki
|
116
121
|
|
117
122
|
### General
|
118
|
-
* [Configuration](rapns/wiki/Configuration)
|
119
|
-
* [Upgrading from 2.x to 3.0](rapns/wiki/Upgrading-from-version-2.x-to-3.0)
|
120
|
-
* [Deploying to Heroku](rapns/wiki/Heroku)
|
121
|
-
* [Hot App Updates](rapns/wiki/Hot-App-Updates)
|
122
|
-
* [
|
123
|
-
* [
|
124
|
-
* [
|
123
|
+
* [Configuration](https://github.com/ileitch/rapns/wiki/Configuration)
|
124
|
+
* [Upgrading from 2.x to 3.0](https://github.com/ileitch/rapns/wiki/Upgrading-from-version-2.x-to-3.0)
|
125
|
+
* [Deploying to Heroku](https://github.com/ileitch/rapns/wiki/Heroku)
|
126
|
+
* [Hot App Updates](https://github.com/ileitch/rapns/wiki/Hot-App-Updates)
|
127
|
+
* [Signals](https://github.com/ileitch/rapns/wiki/Signals)
|
128
|
+
* [Reflection API](https://github.com/ileitch/rapns/wiki/Reflection-API)
|
129
|
+
* [Push API](https://github.com/ileitch/rapns/wiki/Push-API)
|
130
|
+
* [Embedding API](https://github.com/ileitch/rapns/wiki/Embedding-API)
|
125
131
|
|
126
132
|
### APNs
|
127
|
-
* [Advanced APNs Features](rapns/wiki/Advanced-APNs-Features)
|
128
|
-
* [APNs Delivery Failure Handling](rapns/wiki/APNs-Delivery-Failure-Handling)
|
129
|
-
* [Why open multiple connections to the APNs?](rapns/wiki/Why-open-multiple-connections-to-the-APNs%3F)
|
130
|
-
* [Silent failures might be dropped connections](rapns/wiki/Dropped-connections)
|
133
|
+
* [Advanced APNs Features](https://github.com/ileitch/rapns/wiki/Advanced-APNs-Features)
|
134
|
+
* [APNs Delivery Failure Handling](https://github.com/ileitch/rapns/wiki/APNs-Delivery-Failure-Handling)
|
135
|
+
* [Why open multiple connections to the APNs?](https://github.com/ileitch/rapns/wiki/Why-open-multiple-connections-to-the-APNs%3F)
|
136
|
+
* [Silent failures might be dropped connections](https://github.com/ileitch/rapns/wiki/Dropped-connections)
|
131
137
|
|
132
138
|
### GCM
|
133
139
|
|
data/config/database.yml
CHANGED
@@ -17,12 +17,12 @@ class AddGcm < ActiveRecord::Migration
|
|
17
17
|
AddGcm::Rapns::Notification.update_all :type => 'Rapns::Apns::Notification'
|
18
18
|
AddGcm::Rapns::App.update_all :type => 'Rapns::Apns::App'
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
change_column :rapns_notifications, :type, :string, :null => false
|
21
|
+
change_column :rapns_apps, :type, :string, :null => false
|
22
|
+
change_column :rapns_notifications, :device_token, :string, { :null => true, :limit => 64 }
|
23
|
+
change_column :rapns_notifications, :expiry, :integer, { :null => true, :default => 1.day.to_i }
|
24
|
+
change_column :rapns_apps, :environment, :string, :null => true
|
25
|
+
change_column :rapns_apps, :certificate, :text, :null => true
|
26
26
|
|
27
27
|
change_column :rapns_notifications, :error_description, :text
|
28
28
|
change_column :rapns_notifications, :sound, :string, :default => 'default'
|
@@ -47,7 +47,7 @@ class AddGcm < ActiveRecord::Migration
|
|
47
47
|
Rapns::Notification.update_all(['app_id = ?', app.id], ['app = ?', app.name])
|
48
48
|
end
|
49
49
|
|
50
|
-
|
50
|
+
change_column :rapns_notifications, :app_id, :integer, :null => false
|
51
51
|
remove_column :rapns_notifications, :app
|
52
52
|
|
53
53
|
remove_index :rapns_notifications, :name => "index_rapns_notifications_multi"
|
@@ -60,10 +60,10 @@ class AddGcm < ActiveRecord::Migration
|
|
60
60
|
remove_column :rapns_notifications, :type
|
61
61
|
remove_column :rapns_apps, :type
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
63
|
+
change_column :rapns_notifications, :device_token, :string, { :null => false, :limit => 64 }
|
64
|
+
change_column :rapns_notifications, :expiry, :integer, { :null => false, :default => 1.day.to_i }
|
65
|
+
change_column :rapns_apps, :environment, :string, :null => false
|
66
|
+
change_column :rapns_apps, :certificate, :text, :null => false
|
67
67
|
|
68
68
|
change_column :rapns_notifications, :error_description, :string
|
69
69
|
change_column :rapns_notifications, :sound, :string, :default => '1.aiff'
|
@@ -87,7 +87,7 @@ class AddGcm < ActiveRecord::Migration
|
|
87
87
|
Rapns::Notification.update_all(['app = ?', app.key], ['app_id = ?', app.id])
|
88
88
|
end
|
89
89
|
|
90
|
-
|
90
|
+
change_column :rapns_notifications, :key, :string, :null => false
|
91
91
|
remove_column :rapns_notifications, :app_id
|
92
92
|
|
93
93
|
remove_index :rapns_notifications, :name => "index_rapns_notifications_multi"
|
data/lib/rapns/apns/app.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
module Rapns
|
2
2
|
module Apns
|
3
3
|
class App < Rapns::App
|
4
|
-
validates :environment, :presence => true, :inclusion => { :in => %w(development production) }
|
4
|
+
validates :environment, :presence => true, :inclusion => { :in => %w(development production sandbox) }
|
5
5
|
validates :certificate, :presence => true
|
6
6
|
end
|
7
7
|
end
|
8
|
-
end
|
8
|
+
end
|
@@ -2,24 +2,14 @@ module Rapns
|
|
2
2
|
module Daemon
|
3
3
|
module Apns
|
4
4
|
class AppRunner < Rapns::Daemon::AppRunner
|
5
|
-
ENVIRONMENTS = {
|
6
|
-
:production => {
|
7
|
-
:push => ['gateway.push.apple.com', 2195],
|
8
|
-
:feedback => ['feedback.push.apple.com', 2196]
|
9
|
-
},
|
10
|
-
:development => {
|
11
|
-
:push => ['gateway.sandbox.push.apple.com', 2195],
|
12
|
-
:feedback => ['feedback.sandbox.push.apple.com', 2196]
|
13
|
-
}
|
14
|
-
}
|
15
|
-
|
16
5
|
protected
|
17
6
|
|
18
7
|
def started
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
8
|
+
unless Rapns.config.push
|
9
|
+
poll = Rapns.config.feedback_poll
|
10
|
+
@feedback_receiver = FeedbackReceiver.new(app, poll)
|
11
|
+
@feedback_receiver.start
|
12
|
+
end
|
23
13
|
end
|
24
14
|
|
25
15
|
def stopped
|
@@ -27,8 +17,7 @@ module Rapns
|
|
27
17
|
end
|
28
18
|
|
29
19
|
def new_delivery_handler
|
30
|
-
|
31
|
-
DeliveryHandler.new(app, push_host, push_port)
|
20
|
+
DeliveryHandler.new(app)
|
32
21
|
end
|
33
22
|
end
|
34
23
|
end
|
@@ -53,7 +53,7 @@ module Rapns
|
|
53
53
|
retry_count += 1;
|
54
54
|
|
55
55
|
if retry_count == 1
|
56
|
-
Rapns
|
56
|
+
Rapns.logger.error("[#{@app.name}] Lost connection to #{@host}:#{@port} (#{e.class.name}), reconnecting...")
|
57
57
|
reflect(:apns_connection_lost, @app, e)
|
58
58
|
end
|
59
59
|
|
@@ -75,7 +75,7 @@ module Rapns
|
|
75
75
|
protected
|
76
76
|
|
77
77
|
def reconnect_idle
|
78
|
-
Rapns
|
78
|
+
Rapns.logger.info("[#{@app.name}] Idle period exceeded, reconnecting...")
|
79
79
|
reconnect
|
80
80
|
end
|
81
81
|
|
@@ -107,7 +107,7 @@ module Rapns
|
|
107
107
|
ssl_socket = OpenSSL::SSL::SSLSocket.new(tcp_socket, @ssl_context)
|
108
108
|
ssl_socket.sync = true
|
109
109
|
ssl_socket.connect
|
110
|
-
Rapns
|
110
|
+
Rapns.logger.info("[#{@app.name}] Connected to #{@host}:#{@port}")
|
111
111
|
[tcp_socket, ssl_socket]
|
112
112
|
end
|
113
113
|
end
|
@@ -27,7 +27,7 @@ module Rapns
|
|
27
27
|
@connection.write(@notification.to_binary)
|
28
28
|
check_for_error if Rapns.config.check_for_errors
|
29
29
|
mark_delivered
|
30
|
-
Rapns
|
30
|
+
Rapns.logger.info("[#{@app.name}] #{@notification.id} sent to #{@notification.device_token}")
|
31
31
|
rescue Rapns::DeliveryError, Rapns::Apns::DisconnectionError => error
|
32
32
|
mark_failed(error.code, error.description)
|
33
33
|
raise
|
@@ -50,7 +50,7 @@ module Rapns
|
|
50
50
|
end
|
51
51
|
|
52
52
|
begin
|
53
|
-
Rapns
|
53
|
+
Rapns.logger.error("[#{@app.name}] Error received, reconnecting...")
|
54
54
|
@connection.reconnect
|
55
55
|
ensure
|
56
56
|
raise error if error
|
@@ -2,18 +2,32 @@ module Rapns
|
|
2
2
|
module Daemon
|
3
3
|
module Apns
|
4
4
|
class DeliveryHandler < Rapns::Daemon::DeliveryHandler
|
5
|
-
|
5
|
+
HOSTS = {
|
6
|
+
:production => ['gateway.push.apple.com', 2195],
|
7
|
+
:development => ['gateway.sandbox.push.apple.com', 2195], # deprecated
|
8
|
+
:sandbox => ['gateway.sandbox.push.apple.com', 2195]
|
9
|
+
}
|
10
|
+
|
11
|
+
def initialize(app)
|
6
12
|
@app = app
|
7
|
-
@
|
8
|
-
@connection.connect
|
13
|
+
@host, @port = HOSTS[@app.environment.to_sym]
|
9
14
|
end
|
10
15
|
|
11
16
|
def deliver(notification)
|
12
|
-
Rapns::Daemon::Apns::Delivery.perform(@app,
|
17
|
+
Rapns::Daemon::Apns::Delivery.perform(@app, connection, notification)
|
13
18
|
end
|
14
19
|
|
15
20
|
def stopped
|
16
|
-
@connection.close
|
21
|
+
@connection.close if @connection
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
def connection
|
27
|
+
return @connection if defined? @connection
|
28
|
+
connection = Connection.new(@app, @host, @port)
|
29
|
+
connection.connect
|
30
|
+
@connection = connection
|
17
31
|
end
|
18
32
|
end
|
19
33
|
end
|
@@ -7,11 +7,15 @@ module Rapns
|
|
7
7
|
include DatabaseReconnectable
|
8
8
|
|
9
9
|
FEEDBACK_TUPLE_BYTES = 38
|
10
|
+
HOSTS = {
|
11
|
+
:production => ['feedback.push.apple.com', 2196],
|
12
|
+
:development => ['feedback.sandbox.push.apple.com', 2196], # deprecated
|
13
|
+
:sandbox => ['feedback.sandbox.push.apple.com', 2196]
|
14
|
+
}
|
10
15
|
|
11
|
-
def initialize(app,
|
16
|
+
def initialize(app, poll)
|
12
17
|
@app = app
|
13
|
-
@host =
|
14
|
-
@port = port
|
18
|
+
@host, @port = HOSTS[@app.environment.to_sym]
|
15
19
|
@poll = poll
|
16
20
|
@certificate = app.certificate
|
17
21
|
@password = app.password
|
@@ -44,7 +48,7 @@ module Rapns
|
|
44
48
|
create_feedback(timestamp, device_token)
|
45
49
|
end
|
46
50
|
rescue StandardError => e
|
47
|
-
Rapns
|
51
|
+
Rapns.logger.error(e)
|
48
52
|
ensure
|
49
53
|
connection.close if connection
|
50
54
|
end
|
@@ -60,7 +64,7 @@ module Rapns
|
|
60
64
|
def create_feedback(failed_at, device_token)
|
61
65
|
formatted_failed_at = failed_at.strftime("%Y-%m-%d %H:%M:%S UTC")
|
62
66
|
with_database_reconnect_and_retry do
|
63
|
-
Rapns
|
67
|
+
Rapns.logger.info("[#{@app.name}] [FeedbackReceiver] Delivery failed at #{formatted_failed_at} for #{device_token}.")
|
64
68
|
feedback = Rapns::Apns::Feedback.create!(:failed_at => failed_at, :device_token => device_token, :app => @app)
|
65
69
|
reflect(:apns_feedback, feedback)
|
66
70
|
|
@@ -68,7 +72,7 @@ module Rapns
|
|
68
72
|
begin
|
69
73
|
Rapns.config.apns_feedback_callback.call(feedback) if Rapns.config.apns_feedback_callback
|
70
74
|
rescue StandardError => e
|
71
|
-
Rapns
|
75
|
+
Rapns.logger.error(e)
|
72
76
|
end
|
73
77
|
end
|
74
78
|
end
|
@@ -11,7 +11,7 @@ module Rapns
|
|
11
11
|
if app = runners[notification.app_id]
|
12
12
|
app.enqueue(notification)
|
13
13
|
else
|
14
|
-
Rapns
|
14
|
+
Rapns.logger.error("No such app '#{notification.app_id}' for notification #{notification.id}.")
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
@@ -31,8 +31,8 @@ module Rapns
|
|
31
31
|
runner.start
|
32
32
|
runners[app.id] = runner
|
33
33
|
rescue StandardError => e
|
34
|
-
Rapns
|
35
|
-
Rapns
|
34
|
+
Rapns.logger.error("[#{app.name}] Exception raised during startup. Notifications will not be delivered for this app.")
|
35
|
+
Rapns.logger.error(e)
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
@@ -44,6 +44,7 @@ module Rapns
|
|
44
44
|
|
45
45
|
def self.stop
|
46
46
|
runners.values.map(&:stop)
|
47
|
+
runners.clear
|
47
48
|
end
|
48
49
|
|
49
50
|
def self.debug
|
@@ -51,7 +52,11 @@ module Rapns
|
|
51
52
|
end
|
52
53
|
|
53
54
|
def self.idle
|
54
|
-
runners.values.select
|
55
|
+
runners.values.select(&:idle?)
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.wait
|
59
|
+
sleep 0.1 while !runners.values.all?(&:idle?)
|
55
60
|
end
|
56
61
|
|
57
62
|
attr_reader :app
|
@@ -69,12 +74,13 @@ module Rapns
|
|
69
74
|
def start
|
70
75
|
app.connections.times { handlers << start_handler }
|
71
76
|
started
|
72
|
-
Rapns
|
77
|
+
Rapns.logger.info("[#{app.name}] Started, #{handlers_str}.")
|
73
78
|
end
|
74
79
|
|
75
80
|
def stop
|
76
81
|
handlers.map(&:stop)
|
77
82
|
stopped
|
83
|
+
handlers.clear
|
78
84
|
end
|
79
85
|
|
80
86
|
def enqueue(notification)
|
@@ -87,10 +93,10 @@ module Rapns
|
|
87
93
|
return if diff == 0
|
88
94
|
if diff > 0
|
89
95
|
diff.times { decrement_handlers }
|
90
|
-
Rapns
|
96
|
+
Rapns.logger.info("[#{app.name}] Stopped #{handlers_str(diff)}. #{handlers_str} remaining.")
|
91
97
|
else
|
92
98
|
diff.abs.times { increment_handlers }
|
93
|
-
Rapns
|
99
|
+
Rapns.logger.info("[#{app.name}] Started #{handlers_str(diff)}. #{handlers_str} remaining.")
|
94
100
|
end
|
95
101
|
end
|
96
102
|
|
@@ -103,7 +109,7 @@ module Rapns
|
|
103
109
|
end
|
104
110
|
|
105
111
|
def debug
|
106
|
-
Rapns
|
112
|
+
Rapns.logger.info <<-EOS
|
107
113
|
|
108
114
|
#{@app.name}:
|
109
115
|
handlers: #{num_handlers}
|
@@ -16,27 +16,27 @@ module Rapns
|
|
16
16
|
yield
|
17
17
|
end
|
18
18
|
rescue *ADAPTER_ERRORS => e
|
19
|
-
Rapns
|
19
|
+
Rapns.logger.error(e)
|
20
20
|
database_connection_lost
|
21
21
|
retry
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
def database_connection_lost
|
26
|
-
Rapns
|
26
|
+
Rapns.logger.warn("Lost connection to database, reconnecting...")
|
27
27
|
attempts = 0
|
28
28
|
loop do
|
29
29
|
begin
|
30
|
-
Rapns
|
30
|
+
Rapns.logger.warn("Attempt #{attempts += 1}")
|
31
31
|
reconnect_database
|
32
32
|
check_database_is_connected
|
33
33
|
break
|
34
34
|
rescue *ADAPTER_ERRORS => e
|
35
|
-
Rapns
|
35
|
+
Rapns.logger.error(e, :airbrake_notify => false)
|
36
36
|
sleep_to_avoid_thrashing
|
37
37
|
end
|
38
38
|
end
|
39
|
-
Rapns
|
39
|
+
Rapns.logger.warn("Database reconnected")
|
40
40
|
end
|
41
41
|
|
42
42
|
def reconnect_database
|
@@ -54,4 +54,4 @@ module Rapns
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
end
|
57
|
-
end
|
57
|
+
end
|
data/lib/rapns/daemon/feeder.rb
CHANGED
@@ -47,7 +47,7 @@ module Rapns
|
|
47
47
|
|
48
48
|
if body['failure'].to_i == 0
|
49
49
|
mark_delivered
|
50
|
-
Rapns
|
50
|
+
Rapns.logger.info("[#{@app.name}] #{@notification.id} sent to #{@notification.registration_ids.join(', ')}")
|
51
51
|
else
|
52
52
|
handle_errors(response, body)
|
53
53
|
end
|
@@ -79,17 +79,17 @@ module Rapns
|
|
79
79
|
|
80
80
|
def internal_server_error(response)
|
81
81
|
retry_delivery(@notification, response)
|
82
|
-
Rapns
|
82
|
+
Rapns.logger.warn("GCM responded with an Internal Error. " + retry_message)
|
83
83
|
end
|
84
84
|
|
85
85
|
def service_unavailable(response)
|
86
86
|
retry_delivery(@notification, response)
|
87
|
-
Rapns
|
87
|
+
Rapns.logger.warn("GCM responded with an Service Unavailable Error. " + retry_message)
|
88
88
|
end
|
89
89
|
|
90
90
|
def all_devices_unavailable(response)
|
91
91
|
retry_delivery(@notification, response)
|
92
|
-
Rapns
|
92
|
+
Rapns.logger.warn("All recipients unavailable. " + retry_message)
|
93
93
|
end
|
94
94
|
|
95
95
|
def some_devices_unavailable(response, errors)
|
@@ -3,7 +3,7 @@ module Rapns
|
|
3
3
|
module InterruptibleSleep
|
4
4
|
def interruptible_sleep(seconds)
|
5
5
|
@_sleep_check, @_sleep_interrupt = IO.pipe
|
6
|
-
IO.select([@_sleep_check], nil, nil, seconds)
|
6
|
+
IO.select([@_sleep_check], nil, nil, seconds) rescue Errno::EINVAL
|
7
7
|
@_sleep_check.close rescue IOError
|
8
8
|
@_sleep_interrupt.close rescue IOError
|
9
9
|
end
|
@@ -15,4 +15,4 @@ module Rapns
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
18
|
-
end
|
18
|
+
end
|
data/lib/rapns/daemon.rb
CHANGED
@@ -12,7 +12,6 @@ require 'rapns/daemon/database_reconnectable'
|
|
12
12
|
require 'rapns/daemon/delivery'
|
13
13
|
require 'rapns/daemon/delivery_queue'
|
14
14
|
require 'rapns/daemon/feeder'
|
15
|
-
require 'rapns/daemon/logger'
|
16
15
|
require 'rapns/daemon/app_runner'
|
17
16
|
require 'rapns/daemon/delivery_handler'
|
18
17
|
|
@@ -31,14 +30,7 @@ module Rapns
|
|
31
30
|
module Daemon
|
32
31
|
extend DatabaseReconnectable
|
33
32
|
|
34
|
-
class << self
|
35
|
-
attr_accessor :logger
|
36
|
-
end
|
37
|
-
|
38
33
|
def self.start
|
39
|
-
self.logger = Logger.new(:foreground => Rapns.config.foreground,
|
40
|
-
:airbrake_notify => Rapns.config.airbrake_notify)
|
41
|
-
|
42
34
|
setup_signal_traps if trap_signals?
|
43
35
|
|
44
36
|
if daemonize?
|
@@ -47,7 +39,7 @@ module Rapns
|
|
47
39
|
end
|
48
40
|
|
49
41
|
write_pid_file
|
50
|
-
|
42
|
+
Upgraded.check(:exit => true)
|
51
43
|
AppRunner.sync
|
52
44
|
Feeder.start
|
53
45
|
end
|
@@ -62,39 +54,11 @@ module Rapns
|
|
62
54
|
protected
|
63
55
|
|
64
56
|
def self.daemonize?
|
65
|
-
!(Rapns.config.foreground || Rapns.config.embedded ||
|
66
|
-
end
|
67
|
-
|
68
|
-
def self.ensure_upgraded
|
69
|
-
count = 0
|
70
|
-
|
71
|
-
begin
|
72
|
-
count = Rapns::App.count
|
73
|
-
rescue ActiveRecord::StatementInvalid
|
74
|
-
puts "!!!! RAPNS NOT STARTED !!!!"
|
75
|
-
puts
|
76
|
-
puts "As of version v2.0.0 apps are configured in the database instead of rapns.yml."
|
77
|
-
puts "Please run 'rails g rapns' to generate the new migrations and create your app."
|
78
|
-
puts "See https://github.com/ileitch/rapns for further instructions."
|
79
|
-
puts
|
80
|
-
exit 1 unless Rapns.config.embedded || Rapns.config.push
|
81
|
-
end
|
82
|
-
|
83
|
-
if count == 0
|
84
|
-
logger.warn("You have not created an app yet. See https://github.com/ileitch/rapns for instructions.")
|
85
|
-
end
|
86
|
-
|
87
|
-
if File.exists?(File.join(Rails.root, 'config', 'rapns', 'rapns.yml'))
|
88
|
-
logger.warn(<<-EOS)
|
89
|
-
Since 2.0.0 rapns uses command-line options and a Ruby based configuration file.
|
90
|
-
Please run 'rails g rapns' to generate a new configuration file into config/initializers.
|
91
|
-
Remove config/rapns/rapns.yml to avoid this warning.
|
92
|
-
EOS
|
93
|
-
end
|
57
|
+
!(Rapns.config.foreground || Rapns.config.embedded || defined?(JRUBY_VERSION))
|
94
58
|
end
|
95
59
|
|
96
60
|
def self.trap_signals?
|
97
|
-
!
|
61
|
+
!Rapns.config.embedded
|
98
62
|
end
|
99
63
|
|
100
64
|
def self.setup_signal_traps
|
@@ -119,7 +83,7 @@ Remove config/rapns/rapns.yml to avoid this warning.
|
|
119
83
|
begin
|
120
84
|
File.open(Rapns.config.pid_file, 'w') { |f| f.puts Process.pid }
|
121
85
|
rescue SystemCallError => e
|
122
|
-
logger.error("Failed to write PID to '#{Rapns.config.pid_file}': #{e.inspect}")
|
86
|
+
Rapns.logger.error("Failed to write PID to '#{Rapns.config.pid_file}': #{e.inspect}")
|
123
87
|
end
|
124
88
|
end
|
125
89
|
end
|