rapns 3.1.0 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Build Status](https://secure.travis-ci.org/ileitch/rapns.png?branch=master)](http://travis-ci.org/ileitch/rapns)
|
2
|
+
[![Code Climate](https://codeclimate.com/github/ileitch/rapns.png)](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
|