rapns 3.0.0.beta.1 → 3.0.0.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +75 -106
- data/bin/rapns +14 -14
- data/config/database.yml +8 -0
- data/lib/generators/rapns_generator.rb +5 -1
- data/lib/generators/templates/add_gcm.rb +8 -0
- data/lib/generators/templates/rapns.rb +39 -0
- data/lib/rapns.rb +1 -0
- data/lib/rapns/apns/notification.rb +2 -0
- data/lib/rapns/apns/required_fields_validator.rb +14 -0
- data/lib/rapns/configuration.rb +24 -33
- data/lib/rapns/daemon.rb +18 -14
- data/lib/rapns/daemon/apns/app_runner.rb +1 -1
- data/lib/rapns/daemon/apns/delivery.rb +1 -1
- data/lib/rapns/daemon/apns/feedback_receiver.rb +1 -1
- data/lib/rapns/daemon/app_runner.rb +13 -7
- data/lib/rapns/daemon/delivery_handler.rb +0 -4
- data/lib/rapns/daemon/feeder.rb +1 -5
- data/lib/rapns/daemon/logger.rb +22 -9
- data/lib/rapns/version.rb +1 -1
- data/lib/tasks/cane.rake +2 -3
- data/lib/tasks/test.rake +1 -2
- data/spec/unit/apns/notification_spec.rb +12 -2
- data/spec/unit/configuration_spec.rb +38 -0
- data/spec/unit/daemon/apns/app_runner_spec.rb +2 -0
- data/spec/unit/daemon/apns/delivery_spec.rb +10 -4
- data/spec/unit/daemon/apns/disconnection_error_spec.rb +18 -0
- data/spec/unit/daemon/apns/feedback_receiver_spec.rb +7 -7
- data/spec/unit/daemon/app_runner_spec.rb +51 -0
- data/spec/unit/daemon/database_reconnectable_spec.rb +2 -0
- data/spec/unit/daemon/delivery_error_spec.rb +2 -2
- data/spec/unit/daemon/delivery_handler_shared.rb +10 -1
- data/spec/unit/daemon/gcm/app_runner_spec.rb +3 -1
- data/spec/unit/daemon/logger_spec.rb +10 -2
- data/spec/unit/daemon_spec.rb +31 -14
- data/spec/unit_spec_helper.rb +3 -7
- metadata +10 -4
data/README.md
CHANGED
@@ -1,27 +1,24 @@
|
|
1
1
|
[![Build Status](https://secure.travis-ci.org/ileitch/rapns.png?branch=master)](http://travis-ci.org/ileitch/rapns)
|
2
2
|
|
3
|
-
|
3
|
+
### Rapns - Professional grade APNs and GCM daemon
|
4
4
|
|
5
|
-
*
|
6
|
-
*
|
7
|
-
*
|
8
|
-
*
|
9
|
-
*
|
10
|
-
*
|
11
|
-
* [Airbrake](http://airbrakeapp.com/)
|
12
|
-
* Support for [dictionary `alert` properties](#assigning-a-hash-to-alert).
|
13
|
-
* [Mobile Device Management (MDM)](#mobile-device-management)
|
14
|
-
* Stable. Reconnects to the APNs and your database if connections are lost.
|
5
|
+
* Supports both APNs (iOS) and GCM (Google Cloud Messaging, Android).
|
6
|
+
* Seamless Rails integration.
|
7
|
+
* Scalable - choose the number of threads each app spawns.
|
8
|
+
* Designed for uptime - signal -HUP to add, update apps.
|
9
|
+
* Stable - reconnects database and network connections when lost.
|
10
|
+
* Works with MRI, JRuby, Rubinius 1.8 and 1.9.
|
11
|
+
* [Airbrake](http://airbrakeapp.com/) integration.
|
15
12
|
|
16
|
-
### Who uses
|
13
|
+
### Who uses Rapns?
|
17
14
|
|
18
15
|
[GateGuru](http://gateguruapp.com) and [Desk.com](http://desk.com), among others!
|
19
16
|
|
20
|
-
*I'd love to hear if you use
|
17
|
+
*I'd love to hear if you use Rapns - @ileitch on twitter.*
|
21
18
|
|
22
19
|
## Getting Started
|
23
20
|
|
24
|
-
Add
|
21
|
+
Add Rapns to your Gemfile:
|
25
22
|
|
26
23
|
gem 'rapns'
|
27
24
|
|
@@ -44,107 +41,75 @@ Generate the migration, rapns.yml and migrate:
|
|
44
41
|
|
45
42
|
## Create an App
|
46
43
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
44
|
+
#### APNs
|
45
|
+
```ruby
|
46
|
+
app = Rapns::Apns::App.new
|
47
|
+
app.name = "ios_app"
|
48
|
+
app.certificate = File.read("/path/to/development.pem")
|
49
|
+
app.environment = "development"
|
50
|
+
app.password = "certificate password"
|
51
|
+
app.connections = 1
|
52
|
+
app.save!
|
53
|
+
```
|
54
|
+
|
55
|
+
#### GCM
|
56
|
+
```ruby
|
57
|
+
app = Rapns::Gcm::App.new
|
58
|
+
app.name = "android_app"
|
59
|
+
app.auth_key = "..."
|
60
|
+
app.connections = 1
|
61
|
+
app.save!
|
62
|
+
```
|
63
|
+
|
64
|
+
## Create a Notification
|
65
|
+
|
66
|
+
#### APNs
|
67
|
+
```ruby
|
68
|
+
n = Rapns::Apns::Notification.new
|
69
|
+
n.app = Rapns::Apns::App.find_by_name("ios_app")
|
70
|
+
n.device_token = "..."
|
71
|
+
n.alert = "hi mom!"
|
72
|
+
n.attributes_for_device = {:foo => :bar}
|
73
|
+
n.save!
|
74
|
+
```
|
75
|
+
|
76
|
+
#### GCM
|
77
|
+
```ruby
|
78
|
+
n = Rapns::Gcm::Notification.new
|
79
|
+
n.app = Rapns::Gcm::App.find_by_name("android_app")
|
80
|
+
n.registration_ids = ["..."]
|
81
|
+
n.data = {:message => "hi mom!"}
|
82
|
+
n.save!
|
83
|
+
```
|
84
|
+
|
85
|
+
## Starting Rapns
|
62
86
|
|
63
87
|
cd /path/to/rails/app
|
64
|
-
|
65
|
-
|
66
|
-
### Options
|
67
|
-
|
68
|
-
* `-f` `--foreground` Prevent rapns from forking into a daemon.
|
69
|
-
* `-P N` `--db-poll N` Frequency in seconds to check for new notifications. Default: 2.
|
70
|
-
* `-F N` `--feedback-poll N` Frequency in seconds to check for feedback. Default: 60.
|
71
|
-
* `-e` `--no-error-checks` Disables [error checking](#immediately-when-processing-a-notification-for-delivery) after notification delivery. You may want to disable this if you are sending a very high number of notifications.
|
72
|
-
* `-n` `--no-airbrake-notify` Disables error notifications via Airbrake.
|
73
|
-
* `-p PATH` `--pid-file PATH` Path to write PID file. Relative to Rails root unless absolute.
|
74
|
-
* `-b N` `--batch-size N` ActiveRecord batch size of notifications. Increase for possible higher throughput but higher memory footprint. Default: 5000.
|
75
|
-
|
76
|
-
## Sending a Notification
|
77
|
-
|
78
|
-
n = Rapns::Notification.new
|
79
|
-
n.app = "my_app"
|
80
|
-
n.device_token = "934f7a..."
|
81
|
-
n.alert = "This is the message shown on the device."
|
82
|
-
n.badge = 1
|
83
|
-
n.sound = "1.aiff"
|
84
|
-
n.expiry = 1.day.to_i
|
85
|
-
n.attributes_for_device = {"question" => nil, "answer" => 42}
|
86
|
-
n.deliver_after = 1.hour.from_now
|
87
|
-
n.save!
|
88
|
-
|
89
|
-
* `app` must match `key` on an `Rapns::App`.
|
90
|
-
* `sound` defaults to `1.aiff`. You can either set it to a custom .aiff file, or `nil` for no sound.
|
91
|
-
* `expiry` is the time in seconds the APNs (not rapns) will spend trying to deliver the notification to the device. The notification is discarded if it has not been delivered in this time. Default is 1 day.
|
92
|
-
* `attributes_for_device` is the `NSDictionary` argument passed to your iOS app in either `didFinishLaunchingWithOptions` or `didReceiveRemoteNotification`.
|
93
|
-
* `deliver_after` is not required, but may be set if you'd like to delay delivery of the notification to a specific time in the future.
|
94
|
-
|
95
|
-
### Mobile Device Management
|
96
|
-
|
97
|
-
n = Rapns::Notification.new
|
98
|
-
n.mdm = "magic"
|
99
|
-
n.save!
|
100
|
-
|
101
|
-
### Assigning a Hash to alert
|
102
|
-
|
103
|
-
Please refer to Apple's [documentation](http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ApplePushService/ApplePushService.html#//apple_ref/doc/uid/TP40008194-CH100-SW1) (Tables 3-1 and 3-2).
|
104
|
-
|
105
|
-
## Hot App Updates
|
106
|
-
|
107
|
-
If you signal the rapns process with `HUP` it will synchronize with the current `Rapns::App` configurations. This includes adding an app, removing and increasing/decreasing the number of connections an app uses.
|
108
|
-
|
109
|
-
This synchronization process does not pause the delivery of notifications to other apps.
|
88
|
+
rapns <Rails environment> [options]
|
110
89
|
|
111
|
-
|
90
|
+
See [Configuration](wiki/Configuration) for a list of options, or run `rapns --help`.
|
112
91
|
|
113
|
-
|
114
|
-
|
115
|
-
## Delivery Failures
|
116
|
-
|
117
|
-
The APNs provides two mechanism for delivery failure notification:
|
118
|
-
|
119
|
-
### Immediately, when processing a notification for delivery.
|
120
|
-
|
121
|
-
Although rapns makes such errors highly unlikely due to validation, the APNs reports processing errors immediately after being sent a notification. These errors are all centred around the well-formedness of the notification payload. Should a notification be rejected due to such an error, rapns will update the following attributes on the notification and send a notification via Airbrake/Hoptoad (if enabled):
|
122
|
-
|
123
|
-
`failed` flag is set to true.
|
124
|
-
`failed_at` is set to the time of failure.
|
125
|
-
`error` is set to Apple's code for the error.
|
126
|
-
`error_description` is set to a (somewhat brief) description of the error.
|
127
|
-
|
128
|
-
rapns will not attempt to deliver the notification again.
|
129
|
-
|
130
|
-
### Via the Feedback Service.
|
131
|
-
|
132
|
-
rapns checks for feedback periodically and stores results in the `Rapns::Feedback` model. Each record contains the device token and a timestamp of when the APNs determined that the app no longer exists on the device.
|
133
|
-
|
134
|
-
It is your responsibility to avoid creating new notifications for devices that no longer have your app installed. rapns does not and will not check `Rapns::Feedback` before sending notifications.
|
135
|
-
|
136
|
-
*Note: In my testing and from other reports on the Internet, it appears you may not receive feedback when using the APNs sandbox environment.*
|
137
|
-
|
138
|
-
## Updating rapns
|
92
|
+
## Updating Rapns
|
139
93
|
|
140
94
|
After updating you should run `rails g rapns` to check for any new migrations.
|
141
95
|
|
142
96
|
## Wiki
|
143
97
|
|
144
|
-
|
145
|
-
* [
|
98
|
+
### General
|
99
|
+
* [Configuration](wiki/Configuration)
|
100
|
+
* [Upgrading from 2.x to 3.0](wiki/Upgrading-from-version-2.x-to-3.0)
|
101
|
+
* [Deploying to Heroku](wiki/Heroku)
|
102
|
+
* [Hot App Updates](wiki/Hot-App-Updates)
|
146
103
|
|
147
|
-
|
104
|
+
### APNs
|
105
|
+
* [Advanced APNs Features](wiki/Advanced-APNs-Features)
|
106
|
+
* [APNs Delivery Failure Handling](wiki/APNs-Delivery-Failure-Handling)
|
107
|
+
* [Why open multiple connections to the APNs?](wiki/Why-open-multiple-connections-to-the-APNs%3F)
|
108
|
+
* [Silent failures might be dropped connections](wiki/Dropped-connections)
|
109
|
+
|
110
|
+
### GCM
|
111
|
+
|
112
|
+
## Contributing
|
148
113
|
|
149
114
|
Fork as usual and go crazy!
|
150
115
|
|
@@ -152,9 +117,13 @@ When running specs, please note that the ActiveRecord adapter can be changed by
|
|
152
117
|
|
153
118
|
Available adapters for testing are `mysql`, `mysql2` and `postgresql`.
|
154
119
|
|
120
|
+
Note that the database username is changed at runtime to be the currently logged in user's name. So if you're testing
|
121
|
+
with mysql and you're using a user named 'bob', you will need to grant a mysql user 'bob' access to the 'rapns_test'
|
122
|
+
mysql database.
|
123
|
+
|
155
124
|
### Contributors
|
156
125
|
|
157
|
-
Thank you to the following wonderful people for contributing
|
126
|
+
Thank you to the following wonderful people for contributing:
|
158
127
|
|
159
128
|
* [@blakewatters](https://github.com/blakewatters)
|
160
129
|
* [@forresty](https://github.com/forresty)
|
data/bin/rapns
CHANGED
@@ -5,16 +5,23 @@ require 'rapns'
|
|
5
5
|
|
6
6
|
environment = ARGV[0]
|
7
7
|
|
8
|
-
config = Rapns.configuration
|
9
|
-
|
10
8
|
banner = 'Usage: rapns <Rails environment> [options]'
|
9
|
+
if environment.nil? || environment =~ /^-/
|
10
|
+
puts banner
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
|
14
|
+
# A mock configuration to be used before the Rails environment is loaded.
|
15
|
+
class CommandlineConfig < Struct.new(*Rapns::CONFIG_ATTRS); end
|
16
|
+
config = CommandlineConfig.new
|
17
|
+
|
11
18
|
ARGV.options do |opts|
|
12
19
|
opts.banner = banner
|
13
20
|
opts.on('-f', '--foreground', 'Run in the foreground.') { config.foreground = true }
|
14
21
|
opts.on('-P N', '--db-poll N', Integer, "Frequency in seconds to check for new notifications. Default: #{config.push_poll}.") { |n| config.push_poll = n }
|
15
22
|
opts.on('-F N', '--feedback-poll N', Integer, "Frequency in seconds to check for feedback. Default: #{config.feedback_poll}.") { |n| config.feedback_poll = n }
|
16
|
-
opts.on('-e', '--no-error-checks', 'Disable error checking after notification delivery.') { config.
|
17
|
-
opts.on('-n', '--no-airbrake-notify', 'Disables error notifications via Airbrake.') { config.
|
23
|
+
opts.on('-e', '--no-error-checks', 'Disable APNs error checking after notification delivery.') { config.check_for_errors = false }
|
24
|
+
opts.on('-n', '--no-airbrake-notify', 'Disables error notifications via Airbrake.') { config.airbrake_notify = false }
|
18
25
|
opts.on('-p PATH', '--pid-file PATH', String, 'Path to write PID file. Relative to Rails root unless absolute.') { |path| config.pid_file = path }
|
19
26
|
opts.on('-b N', '--batch-size N', Integer, 'ActiveRecord notifications batch size.') { |n| config.batch_size = n }
|
20
27
|
opts.on('-v', '--version', 'Print this version of rapns.') { puts "rapns #{Rapns::VERSION}"; exit }
|
@@ -22,20 +29,13 @@ ARGV.options do |opts|
|
|
22
29
|
opts.parse!
|
23
30
|
end
|
24
31
|
|
25
|
-
if environment.nil? || environment =~ /^-/
|
26
|
-
puts banner
|
27
|
-
exit 1
|
28
|
-
end
|
29
|
-
|
30
32
|
ENV['RAILS_ENV'] = environment
|
31
33
|
load 'config/environment.rb'
|
32
34
|
load 'config/initializers/rapns.rb' if File.exist?('config/initializers/rapns.rb')
|
33
35
|
|
36
|
+
Rapns.config.update(config)
|
37
|
+
|
34
38
|
require 'rapns/daemon'
|
35
39
|
require 'rapns/patches'
|
36
40
|
|
37
|
-
|
38
|
-
config.pid_file = File.join(Rails.root, config.pid_file)
|
39
|
-
end
|
40
|
-
|
41
|
-
Rapns::Daemon.start(config)
|
41
|
+
Rapns::Daemon.start
|
data/config/database.yml
CHANGED
@@ -18,6 +18,10 @@ class RapnsGenerator < Rails::Generators::Base
|
|
18
18
|
add_rapns_migration('add_gcm')
|
19
19
|
end
|
20
20
|
|
21
|
+
def copy_config
|
22
|
+
copy_file 'rapns.rb', 'config/initializers/rapns.rb'
|
23
|
+
end
|
24
|
+
|
21
25
|
protected
|
22
26
|
|
23
27
|
def add_rapns_migration(template)
|
@@ -27,4 +31,4 @@ class RapnsGenerator < Rails::Generators::Base
|
|
27
31
|
migration_template "#{template}.rb", "db/migrate/#{template}.rb"
|
28
32
|
end
|
29
33
|
end
|
30
|
-
end
|
34
|
+
end
|
@@ -25,6 +25,7 @@ class AddGcm < ActiveRecord::Migration
|
|
25
25
|
change_column_null :rapns_apps, :certificate, true
|
26
26
|
|
27
27
|
change_column :rapns_notifications, :error_description, :text
|
28
|
+
change_column :rapns_notifications, :sound, :string, :default => 'default'
|
28
29
|
|
29
30
|
rename_column :rapns_notifications, :attributes_for_device, :data
|
30
31
|
rename_column :rapns_apps, :key, :name
|
@@ -46,6 +47,9 @@ class AddGcm < ActiveRecord::Migration
|
|
46
47
|
|
47
48
|
change_column_null :rapns_notifications, :app_id, false
|
48
49
|
remove_column :rapns_notifications, :app
|
50
|
+
|
51
|
+
remove_index :rapns_notifications, :name => "index_rapns_notifications_multi"
|
52
|
+
add_index :rapns_notifications, [:app_id, :delivered, :failed, :deliver_after], :name => "index_rapns_notifications_multi"
|
49
53
|
end
|
50
54
|
|
51
55
|
def self.down
|
@@ -60,6 +64,7 @@ class AddGcm < ActiveRecord::Migration
|
|
60
64
|
change_column_null :rapns_apps, :certificate, false
|
61
65
|
|
62
66
|
change_column :rapns_notifications, :error_description, :string
|
67
|
+
change_column :rapns_notifications, :sound, :string, :default => '1.aiff'
|
63
68
|
|
64
69
|
rename_column :rapns_notifications, :data, :attributes_for_device
|
65
70
|
rename_column :rapns_apps, :name, :key
|
@@ -82,5 +87,8 @@ class AddGcm < ActiveRecord::Migration
|
|
82
87
|
|
83
88
|
change_column_null :rapns_notifications, :key, false
|
84
89
|
remove_column :rapns_notifications, :app_id
|
90
|
+
|
91
|
+
remove_index :rapns_notifications, :name => "index_rapns_notifications_multi"
|
92
|
+
add_index :rapns_notifications, [:delivered, :failed, :deliver_after], :name => "index_rapns_notifications_multi"
|
85
93
|
end
|
86
94
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# Rapns configuration. Options set here are overridden by command-line options.
|
2
|
+
|
3
|
+
Rapns.configure do |config|
|
4
|
+
|
5
|
+
# Run in the foreground?
|
6
|
+
# config.foreground = false
|
7
|
+
|
8
|
+
# Frequency in seconds to check for new notifications.
|
9
|
+
# config.push_poll = 2
|
10
|
+
|
11
|
+
# Frequency in seconds to check for feedback
|
12
|
+
# config.feedback_poll = 60
|
13
|
+
|
14
|
+
# Enable/Disable error notifications via Airbrake.
|
15
|
+
# config.airbrake_notify = true
|
16
|
+
|
17
|
+
# Disable APNs error checking after notification delivery.
|
18
|
+
# config.check_for_errors = true
|
19
|
+
|
20
|
+
# ActiveRecord notifications batch size.
|
21
|
+
# config.batch_size = 5000
|
22
|
+
|
23
|
+
# Path to write PID file. Relative to Rails root unless absolute.
|
24
|
+
# config.pid_file = '/path/to/rapns.pid'
|
25
|
+
|
26
|
+
# Define a block that will be called with a Rapns::Apns::Feedback instance
|
27
|
+
# when feedback is received from the APNs that a notification has
|
28
|
+
# failed to be delivered. Further notifications should not be sent to the device.
|
29
|
+
#
|
30
|
+
# Example:
|
31
|
+
# config.on_apns_feedback do |feedback|
|
32
|
+
# device = Device.find_by_device_token(feedback.device_token)
|
33
|
+
# if device
|
34
|
+
# device.active = false
|
35
|
+
# device.save!
|
36
|
+
# end
|
37
|
+
# end
|
38
|
+
|
39
|
+
end
|
data/lib/rapns.rb
CHANGED
@@ -9,6 +9,7 @@ require 'rapns/configuration'
|
|
9
9
|
|
10
10
|
require 'rapns/apns/binary_notification_validator'
|
11
11
|
require 'rapns/apns/device_token_format_validator'
|
12
|
+
require 'rapns/apns/required_fields_validator'
|
12
13
|
require 'rapns/apns/notification'
|
13
14
|
require 'rapns/apns/feedback'
|
14
15
|
require 'rapns/apns/app'
|
@@ -8,6 +8,7 @@ module Rapns
|
|
8
8
|
|
9
9
|
validates_with Rapns::Apns::DeviceTokenFormatValidator
|
10
10
|
validates_with Rapns::Apns::BinaryNotificationValidator
|
11
|
+
validates_with Rapns::Apns::RequiredFieldsValidator
|
11
12
|
|
12
13
|
alias_method :attributes_for_device=, :data=
|
13
14
|
alias_method :attributes_for_device, :data
|
@@ -79,6 +80,7 @@ module Rapns
|
|
79
80
|
id_for_pack = options[:for_validation] ? 0 : id
|
80
81
|
[1, id_for_pack, expiry, 0, 32, device_token, payload_size, payload].pack("cNNccH*na*")
|
81
82
|
end
|
83
|
+
|
82
84
|
end
|
83
85
|
end
|
84
86
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Rapns
|
2
|
+
module Apns
|
3
|
+
class RequiredFieldsValidator < ActiveModel::Validator
|
4
|
+
|
5
|
+
# Notifications must contain one of alert, badge or sound as per:
|
6
|
+
# https://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ApplePushService/ApplePushService.html
|
7
|
+
def validate(record)
|
8
|
+
if record.alert.nil? && record.badge.nil? && record.sound.nil?
|
9
|
+
record.errors[:base] << "APN Notification must contain one of alert, badge, or sound"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/rapns/configuration.rb
CHANGED
@@ -1,28 +1,21 @@
|
|
1
1
|
module Rapns
|
2
|
-
|
3
|
-
|
4
|
-
def self.configuration
|
5
|
-
@configuration ||= Rapns::Configuration.new
|
2
|
+
def self.config
|
3
|
+
@config ||= Rapns::Configuration.new
|
6
4
|
end
|
7
5
|
|
8
|
-
# Call the given block yielding to it the global Rapns::Configuration instance for setting
|
9
|
-
# configuration values / callbacks.
|
10
|
-
#
|
11
|
-
# Typically this would be used in your Rails application's config/initializers/rapns.rb file
|
12
6
|
def self.configure
|
13
|
-
yield
|
7
|
+
yield config if block_given?
|
14
8
|
end
|
15
9
|
|
16
|
-
|
17
|
-
|
10
|
+
CONFIG_ATTRS = [:foreground, :push_poll, :feedback_poll,
|
11
|
+
:airbrake_notify, :check_for_errors, :pid_file, :batch_size]
|
18
12
|
|
19
|
-
|
13
|
+
class Configuration < Struct.new(*CONFIG_ATTRS)
|
14
|
+
attr_accessor :apns_feedback_callback
|
20
15
|
|
21
|
-
# Initialize the Config with default values
|
22
16
|
def initialize
|
23
17
|
super
|
24
18
|
|
25
|
-
# defaults:
|
26
19
|
self.foreground = false
|
27
20
|
self.push_poll = 2
|
28
21
|
self.feedback_poll = 60
|
@@ -31,25 +24,23 @@ module Rapns
|
|
31
24
|
self.batch_size = 5000
|
32
25
|
end
|
33
26
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
def on_feedback(&block)
|
52
|
-
self.feedback_callback = block
|
27
|
+
def update(other)
|
28
|
+
CONFIG_ATTRS.each do |attr|
|
29
|
+
other_value = other.send(attr)
|
30
|
+
send("#{attr}=", other_value) unless other_value.nil?
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def on_apns_feedback(&block)
|
35
|
+
self.apns_feedback_callback = block
|
36
|
+
end
|
37
|
+
|
38
|
+
def pid_file=(path)
|
39
|
+
if path && !Pathname.new(path).absolute?
|
40
|
+
super(File.join(Rails.root, path))
|
41
|
+
else
|
42
|
+
super
|
43
|
+
end
|
53
44
|
end
|
54
45
|
end
|
55
46
|
end
|