rpush 2.0.0.rc1-java → 2.0.1-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 +6 -1
 - data/README.md +29 -14
 - data/bin/rpush +2 -2
 - data/lib/generators/templates/rpush.rb +4 -1
 - data/lib/generators/templates/rpush_2_0_0_updates.rb +2 -2
 - data/lib/rpush/client/redis/app.rb +2 -0
 - data/lib/rpush/daemon.rb +1 -1
 - data/lib/rpush/daemon/app_runner.rb +12 -1
 - data/lib/rpush/daemon/signal_handler.rb +24 -19
 - data/lib/rpush/daemon/synchronizer.rb +21 -5
 - data/lib/rpush/daemon/tcp_connection.rb +6 -0
 - data/lib/rpush/reflection.rb +1 -1
 - data/lib/rpush/version.rb +1 -1
 - data/spec/functional/apns_spec.rb +10 -11
 - data/spec/functional/synchronization_spec.rb +22 -0
 - data/spec/unit/daemon/app_runner_spec.rb +2 -2
 - data/spec/unit/daemon/signal_handler_spec.rb +23 -0
 - data/spec/unit/daemon/tcp_connection_spec.rb +17 -0
 - metadata +4 -4
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 13082e421fbc9ede84fe1dea84373de5ccab8bd5
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: c1b695784b56de4a796e75402c808d015f7d9c8f
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: bc6c33f58cb98c3f5a0958fc8a11b554b375aae30e3ad0f44d61a5ddb91da5ae970e0fd4c7b8fe35d773771dedd37b011a4527030df023e7587fa2b5eb49f04c
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 44ebe64b26b051db0e0ae5acb1bfb91cd1ec0efc6a2658138f2a1c493be013f8785683e46ba9a39d2c4c93f7f4bbef101c2a4a7dddca70278fa43544a3861c93
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    | 
         @@ -1,4 +1,8 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            ## 2.0. 
     | 
| 
      
 1 
     | 
    
         
            +
            ## 2.0.1 (Sept 13, 2014)
         
     | 
| 
      
 2 
     | 
    
         
            +
              * Add ssl_certificate_revoked reflection (#68).
         
     | 
| 
      
 3 
     | 
    
         
            +
              * Fix for Postgis support in 2.0.0 migration (#70).
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            ## 2.0.0 (Sept 6, 2014)
         
     | 
| 
       2 
6 
     | 
    
         
             
              * Use APNs enhanced binary format version 2.
         
     | 
| 
       3 
7 
     | 
    
         
             
              * Support running multiple Rpush processes when using ActiveRecord and Redis.
         
     | 
| 
       4 
8 
     | 
    
         
             
              * APNs error detection is now performed asynchronously, 'check_for_errors' is therefore deprecated.
         
     | 
| 
         @@ -11,6 +15,7 @@ 
     | 
|
| 
       11 
15 
     | 
    
         
             
              * The 'batch_storage_updates' config option has been deprecated, storage backends will now always batch updates where appropriate.
         
     | 
| 
       12 
16 
     | 
    
         
             
              * The rpush process title updates with number of queued notifications and number of dispatchers.
         
     | 
| 
       13 
17 
     | 
    
         
             
              * Rpush::Apns::Feedback#app has been renamed to app_id and is now an Integer.
         
     | 
| 
      
 18 
     | 
    
         
            +
              * An app is restarted when the HUP signal is received if its certificate or environment attribute changed.
         
     | 
| 
       14 
19 
     | 
    
         | 
| 
       15 
20 
     | 
    
         
             
            ## 1.0.0 (Feb 9, 2014)
         
     | 
| 
       16 
21 
     | 
    
         
             
              * Renamed to Rpush (from Rapns). Version number reset to 1.0.0.
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -7,15 +7,21 @@ 
     | 
|
| 
       7 
7 
     | 
    
         | 
| 
       8 
8 
     | 
    
         
             
            ### Rpush. The push notification service for Ruby.
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
            *  
     | 
| 
       11 
     | 
    
         
            -
              * **Apple Push Notification Service**
         
     | 
| 
       12 
     | 
    
         
            -
              * **Google Cloud Messaging**
         
     | 
| 
       13 
     | 
    
         
            -
              * **Amazon Device Messaging**
         
     | 
| 
       14 
     | 
    
         
            -
              * **Windows Phone Push Notification Service 
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
            *  
     | 
| 
       17 
     | 
    
         
            -
            *  
     | 
| 
       18 
     | 
    
         
            -
            *  
     | 
| 
      
 10 
     | 
    
         
            +
            * Supported services:
         
     | 
| 
      
 11 
     | 
    
         
            +
              * [**Apple Push Notification Service**](#apple-push-notification-service)
         
     | 
| 
      
 12 
     | 
    
         
            +
              * [**Google Cloud Messaging**](#google-cloud-messaging)
         
     | 
| 
      
 13 
     | 
    
         
            +
              * [**Amazon Device Messaging**](#amazon-device-messaging)
         
     | 
| 
      
 14 
     | 
    
         
            +
              * [**Windows Phone Push Notification Service**](#windows-phone-notification-service)
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            * Supported storage backends:
         
     | 
| 
      
 17 
     | 
    
         
            +
              * **ActiveRecord**
         
     | 
| 
      
 18 
     | 
    
         
            +
              * **Redis**
         
     | 
| 
      
 19 
     | 
    
         
            +
              * More coming!
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            * Seamless Rails integration (3 & 4) .
         
     | 
| 
      
 22 
     | 
    
         
            +
            * Scales vertically (threading) and horizontally (multiple processes).
         
     | 
| 
      
 23 
     | 
    
         
            +
            * Designed for uptime - new apps are loaded automatically, signal `HUP` to update running apps.
         
     | 
| 
      
 24 
     | 
    
         
            +
            * Run as a daemon or inside an [existing process](https://github.com/rpush/rpush/wiki/Embedding-API).
         
     | 
| 
       19 
25 
     | 
    
         
             
            * Use in a scheduler for low-workload deployments ([Push API](https://github.com/rpush/rpush/wiki/Push-API)).
         
     | 
| 
       20 
26 
     | 
    
         
             
            * Hooks for fine-grained instrumentation and error handling ([Reflection API](https://github.com/rpush/rpush/wiki/Reflection-API)).
         
     | 
| 
       21 
27 
     | 
    
         
             
            * Works with MRI, JRuby and Rubinius.
         
     | 
| 
         @@ -122,31 +128,40 @@ n.alert = "..." 
     | 
|
| 
       122 
128 
     | 
    
         
             
            n.save!
         
     | 
| 
       123 
129 
     | 
    
         
             
            ```
         
     | 
| 
       124 
130 
     | 
    
         | 
| 
       125 
     | 
    
         
            -
            ###  
     | 
| 
      
 131 
     | 
    
         
            +
            ### Running Rpush
         
     | 
| 
       126 
132 
     | 
    
         | 
| 
       127 
     | 
    
         
            -
             
     | 
| 
      
 133 
     | 
    
         
            +
            It is recommended to run Rpush as a separate process in most cases, though embedding and manual modes are provided for low-workload environments.
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
            #### As a daemon (recommended):
         
     | 
| 
       128 
136 
     | 
    
         | 
| 
       129 
137 
     | 
    
         
             
                cd /path/to/rails/app
         
     | 
| 
       130 
138 
     | 
    
         
             
                rpush <Rails environment> [options]
         
     | 
| 
       131 
139 
     | 
    
         | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
      
 140 
     | 
    
         
            +
            #### Embedded inside an existing process
         
     | 
| 
       133 
141 
     | 
    
         | 
| 
       134 
142 
     | 
    
         
             
            ```ruby
         
     | 
| 
      
 143 
     | 
    
         
            +
            # Call this during startup of your application, for example, by adding it to the end of config/initializers/rpush.rb
         
     | 
| 
       135 
144 
     | 
    
         
             
            Rpush.embed
         
     | 
| 
       136 
145 
     | 
    
         
             
            ```
         
     | 
| 
       137 
146 
     | 
    
         | 
| 
       138 
     | 
    
         
            -
             
     | 
| 
      
 147 
     | 
    
         
            +
            See [Embedding API](https://github.com/rpush/rpush/wiki/Embedding-API) for more details.
         
     | 
| 
      
 148 
     | 
    
         
            +
             
     | 
| 
      
 149 
     | 
    
         
            +
            #### Manually (in a scheduler)
         
     | 
| 
       139 
150 
     | 
    
         | 
| 
       140 
151 
     | 
    
         
             
            ```ruby
         
     | 
| 
       141 
152 
     | 
    
         
             
            Rpush.push
         
     | 
| 
       142 
153 
     | 
    
         
             
            Rpush.apns_feedback
         
     | 
| 
       143 
154 
     | 
    
         
             
            ```
         
     | 
| 
       144 
155 
     | 
    
         | 
| 
      
 156 
     | 
    
         
            +
            See [Push API](https://github.com/rpush/rpush/wiki/Push-API) for more details.
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
            ### Configuration
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
       145 
160 
     | 
    
         
             
            See [Configuration](https://github.com/rpush/rpush/wiki/Configuration) for a list of options, or run `rpush --help`.
         
     | 
| 
       146 
161 
     | 
    
         | 
| 
       147 
162 
     | 
    
         
             
            ### Updating Rpush
         
     | 
| 
       148 
163 
     | 
    
         | 
| 
       149 
     | 
    
         
            -
             
     | 
| 
      
 164 
     | 
    
         
            +
            If you're using ActiveRecord, you should run `rails g rpush` after upgrading Rpush to check for any new migrations.
         
     | 
| 
       150 
165 
     | 
    
         | 
| 
       151 
166 
     | 
    
         
             
            ### Wiki
         
     | 
| 
       152 
167 
     | 
    
         | 
    
        data/bin/rpush
    CHANGED
    
    | 
         @@ -12,10 +12,10 @@ options = ARGV.options do |opts| 
     | 
|
| 
       12 
12 
     | 
    
         
             
              opts.on('-f', '--foreground', 'Run in the foreground.') { config.foreground = true }
         
     | 
| 
       13 
13 
     | 
    
         
             
              opts.on('-P N', '--db-poll N', Integer, "Frequency in seconds to check for new notifications.") { |n| config.push_poll = n }
         
     | 
| 
       14 
14 
     | 
    
         
             
              opts.on('-F N', '--feedback-poll N', Integer, "Frequency in seconds to check for feedback.") { |n| config.feedback_poll = n }
         
     | 
| 
       15 
     | 
    
         
            -
              opts.on('-e', '--no-error-checks', 'Disable APNs error checking after notification delivery.') { config.check_for_errors = false }
         
     | 
| 
      
 15 
     | 
    
         
            +
              opts.on('-e', '--no-error-checks', 'Disable APNs error checking after notification delivery.') { config.check_for_errors = false } # deprecated
         
     | 
| 
       16 
16 
     | 
    
         
             
              opts.on('-p PATH', '--pid-file PATH', String, 'Path to write PID file. Relative to Rails root unless absolute.') { |path| config.pid_file = path }
         
     | 
| 
       17 
17 
     | 
    
         
             
              opts.on('-b N', '--batch-size N', Integer, 'Storage backend notification batch size.') { |n| config.batch_size = n }
         
     | 
| 
       18 
     | 
    
         
            -
              opts.on('-B', '--[no-]batch-storage-updates', 'Perform storage updates in batches.') { |v| config.batch_storage_updates = v }
         
     | 
| 
      
 18 
     | 
    
         
            +
              opts.on('-B', '--[no-]batch-storage-updates', 'Perform storage updates in batches.') { |v| config.batch_storage_updates = v } # deprecated
         
     | 
| 
       19 
19 
     | 
    
         
             
              opts.on('-v', '--version', 'Print the version.') do
         
     | 
| 
       20 
20 
     | 
    
         
             
                puts "rpush #{Rpush::VERSION}"
         
     | 
| 
       21 
21 
     | 
    
         
             
                exit
         
     | 
| 
         @@ -106,6 +106,10 @@ Rpush.reflect do |on| 
     | 
|
| 
       106 
106 
     | 
    
         
             
              # on.ssl_certificate_will_expire do |app, expiration_time|
         
     | 
| 
       107 
107 
     | 
    
         
             
              # end
         
     | 
| 
       108 
108 
     | 
    
         | 
| 
      
 109 
     | 
    
         
            +
              # Called when an SSL certificate has been revoked.
         
     | 
| 
      
 110 
     | 
    
         
            +
              # on.ssl_certificate_revoked do |app, error|
         
     | 
| 
      
 111 
     | 
    
         
            +
              # end
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
       109 
113 
     | 
    
         
             
              # Called when the ADM returns a canonical registration ID.
         
     | 
| 
       110 
114 
     | 
    
         
             
              # You will need to replace old_id with canonical_id in your records.
         
     | 
| 
       111 
115 
     | 
    
         
             
              # on.adm_canonical_id do |old_id, canonical_id|
         
     | 
| 
         @@ -119,7 +123,6 @@ Rpush.reflect do |on| 
     | 
|
| 
       119 
123 
     | 
    
         
             
              # on.adm_failed_to_recipient do |notification, registration_id, reason|
         
     | 
| 
       120 
124 
     | 
    
         
             
              # end
         
     | 
| 
       121 
125 
     | 
    
         | 
| 
       122 
     | 
    
         
            -
             
     | 
| 
       123 
126 
     | 
    
         
             
              # Called when an exception is raised.
         
     | 
| 
       124 
127 
     | 
    
         
             
              # on.error do |error|
         
     | 
| 
       125 
128 
     | 
    
         
             
              # end
         
     | 
| 
         @@ -7,7 +7,7 @@ class Rpush200Updates < ActiveRecord::Migration 
     | 
|
| 
       7 
7 
     | 
    
         
             
                  remove_index :rpush_notifications, name: :index_rpush_notifications_multi
         
     | 
| 
       8 
8 
     | 
    
         
             
                end
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
                add_index :rpush_notifications, [: 
     | 
| 
      
 10 
     | 
    
         
            +
                add_index :rpush_notifications, [:delivered, :failed], name: 'index_rpush_notifications_multi', where: 'NOT delivered AND NOT failed'
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
                rename_column :rpush_feedback, :app, :app_id
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
         @@ -37,6 +37,6 @@ class Rpush200Updates < ActiveRecord::Migration 
     | 
|
| 
       37 
37 
     | 
    
         
             
              end
         
     | 
| 
       38 
38 
     | 
    
         | 
| 
       39 
39 
     | 
    
         
             
              def self.postgresql?
         
     | 
| 
       40 
     | 
    
         
            -
                adapter_name =~ /postgresql/
         
     | 
| 
      
 40 
     | 
    
         
            +
                adapter_name =~ /postgresql|postgis/
         
     | 
| 
       41 
41 
     | 
    
         
             
              end
         
     | 
| 
       42 
42 
     | 
    
         
             
            end
         
     | 
    
        data/lib/rpush/daemon.rb
    CHANGED
    
    
| 
         @@ -4,7 +4,9 @@ module Rpush 
     | 
|
| 
       4 
4 
     | 
    
         
             
                  extend Reflectable
         
     | 
| 
       5 
5 
     | 
    
         
             
                  include Reflectable
         
     | 
| 
       6 
6 
     | 
    
         
             
                  include Loggable
         
     | 
| 
      
 7 
     | 
    
         
            +
                  extend Loggable
         
     | 
| 
       7 
8 
     | 
    
         
             
                  include StringHelpers
         
     | 
| 
      
 9 
     | 
    
         
            +
                  extend StringHelpers
         
     | 
| 
       8 
10 
     | 
    
         | 
| 
       9 
11 
     | 
    
         
             
                  @runners = {}
         
     | 
| 
       10 
12 
     | 
    
         | 
| 
         @@ -24,6 +26,7 @@ module Rpush 
     | 
|
| 
       24 
26 
     | 
    
         
             
                  def self.start_app(app)
         
     | 
| 
       25 
27 
     | 
    
         
             
                    @runners[app.id] = new(app)
         
     | 
| 
       26 
28 
     | 
    
         
             
                    @runners[app.id].start
         
     | 
| 
      
 29 
     | 
    
         
            +
                    log_info("[#{app.name}] Started, #{pluralize(app.connections, 'dispatcher')}.")
         
     | 
| 
       27 
30 
     | 
    
         
             
                  rescue StandardError => e
         
     | 
| 
       28 
31 
     | 
    
         
             
                    @runners.delete(app.id)
         
     | 
| 
       29 
32 
     | 
    
         
             
                    Rpush.logger.error("[#{app.name}] Exception raised during startup. Notifications will not be delivered for this app.")
         
     | 
| 
         @@ -32,7 +35,15 @@ module Rpush 
     | 
|
| 
       32 
35 
     | 
    
         
             
                  end
         
     | 
| 
       33 
36 
     | 
    
         | 
| 
       34 
37 
     | 
    
         
             
                  def self.stop_app(app_id)
         
     | 
| 
       35 
     | 
    
         
            -
                    @runners.delete(app_id) 
     | 
| 
      
 38 
     | 
    
         
            +
                    runner = @runners.delete(app_id)
         
     | 
| 
      
 39 
     | 
    
         
            +
                    if runner
         
     | 
| 
      
 40 
     | 
    
         
            +
                      runner.stop
         
     | 
| 
      
 41 
     | 
    
         
            +
                      log_info("[#{runner.app.name}] Stopped.")
         
     | 
| 
      
 42 
     | 
    
         
            +
                    end
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                  def self.app_with_id(app_id)
         
     | 
| 
      
 46 
     | 
    
         
            +
                    @runners[app_id].app
         
     | 
| 
       36 
47 
     | 
    
         
             
                  end
         
     | 
| 
       37 
48 
     | 
    
         | 
| 
       38 
49 
     | 
    
         
             
                  def self.app_running?(app)
         
     | 
| 
         @@ -7,42 +7,47 @@ module Rpush 
     | 
|
| 
       7 
7 
     | 
    
         | 
| 
       8 
8 
     | 
    
         
             
                  def self.start
         
     | 
| 
       9 
9 
     | 
    
         
             
                    return unless trap_signals?
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
       11 
11 
     | 
    
         
             
                    read_io, @write_io = IO.pipe
         
     | 
| 
       12 
12 
     | 
    
         
             
                    start_handler(read_io)
         
     | 
| 
       13 
13 
     | 
    
         
             
                    %w(INT TERM HUP USR2).each do |signal|
         
     | 
| 
       14 
     | 
    
         
            -
                      Signal.trap(signal) { @write_io. 
     | 
| 
      
 14 
     | 
    
         
            +
                      Signal.trap(signal) { @write_io.puts(signal) }
         
     | 
| 
       15 
15 
     | 
    
         
             
                    end
         
     | 
| 
       16 
16 
     | 
    
         
             
                  end
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
18 
     | 
    
         
             
                  def self.stop
         
     | 
| 
       19 
     | 
    
         
            -
                    @write_io. 
     | 
| 
      
 19 
     | 
    
         
            +
                    @write_io.puts('break') if @write_io
         
     | 
| 
       20 
20 
     | 
    
         
             
                    @thread.join if @thread
         
     | 
| 
       21 
21 
     | 
    
         
             
                  end
         
     | 
| 
       22 
22 
     | 
    
         | 
| 
       23 
23 
     | 
    
         
             
                  def self.start_handler(read_io)
         
     | 
| 
       24 
24 
     | 
    
         
             
                    @thread = Thread.new do
         
     | 
| 
       25 
     | 
    
         
            -
                       
     | 
| 
       26 
     | 
    
         
            -
                         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
                           
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
                           
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
                           
     | 
| 
      
 25 
     | 
    
         
            +
                      while readable_io = IO.select([read_io]) # rubocop:disable AssignmentInCondition
         
     | 
| 
      
 26 
     | 
    
         
            +
                        signal = readable_io.first[0].gets.strip
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                        begin
         
     | 
| 
      
 29 
     | 
    
         
            +
                          case signal
         
     | 
| 
      
 30 
     | 
    
         
            +
                          when 'HUP'
         
     | 
| 
      
 31 
     | 
    
         
            +
                            Synchronizer.sync
         
     | 
| 
      
 32 
     | 
    
         
            +
                            Feeder.wakeup
         
     | 
| 
      
 33 
     | 
    
         
            +
                          when 'USR2'
         
     | 
| 
      
 34 
     | 
    
         
            +
                            AppRunner.debug
         
     | 
| 
      
 35 
     | 
    
         
            +
                          when 'INT', 'TERM'
         
     | 
| 
      
 36 
     | 
    
         
            +
                            Thread.new { Rpush::Daemon.shutdown }
         
     | 
| 
      
 37 
     | 
    
         
            +
                            break
         
     | 
| 
      
 38 
     | 
    
         
            +
                          when 'break'
         
     | 
| 
      
 39 
     | 
    
         
            +
                            break
         
     | 
| 
      
 40 
     | 
    
         
            +
                          else
         
     | 
| 
      
 41 
     | 
    
         
            +
                            Rpush.logger.error("Unhandled signal: #{signal}")
         
     | 
| 
      
 42 
     | 
    
         
            +
                          end
         
     | 
| 
      
 43 
     | 
    
         
            +
                        rescue StandardError => e
         
     | 
| 
      
 44 
     | 
    
         
            +
                          Rpush.logger.error("Error raised when hndling signal '#{signal}'")
         
     | 
| 
      
 45 
     | 
    
         
            +
                          Rpush.logger.error(e)
         
     | 
| 
       36 
46 
     | 
    
         
             
                        end
         
     | 
| 
       37 
47 
     | 
    
         
             
                      end
         
     | 
| 
       38 
48 
     | 
    
         
             
                    end
         
     | 
| 
       39 
49 
     | 
    
         
             
                  end
         
     | 
| 
       40 
50 
     | 
    
         | 
| 
       41 
     | 
    
         
            -
                  def self.handle_shutdown_signal
         
     | 
| 
       42 
     | 
    
         
            -
                    @shutting_down = true
         
     | 
| 
       43 
     | 
    
         
            -
                    Rpush::Daemon.shutdown
         
     | 
| 
       44 
     | 
    
         
            -
                  end
         
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
51 
     | 
    
         
             
                  def self.trap_signals?
         
     | 
| 
       47 
52 
     | 
    
         
             
                    !Rpush.config.embedded
         
     | 
| 
       48 
53 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -14,13 +14,19 @@ module Rpush 
     | 
|
| 
       14 
14 
     | 
    
         
             
                  end
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
16 
     | 
    
         
             
                  def self.sync_app(app)
         
     | 
| 
       17 
     | 
    
         
            -
                     
     | 
| 
      
 17 
     | 
    
         
            +
                    if !AppRunner.app_running?(app)
         
     | 
| 
       18 
18 
     | 
    
         
             
                      AppRunner.start_app(app)
         
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
                       
     | 
| 
      
 19 
     | 
    
         
            +
                    elsif certificate_changed?(app)
         
     | 
| 
      
 20 
     | 
    
         
            +
                      log_info("[#{app.name}] Certificate changed, restarting...")
         
     | 
| 
      
 21 
     | 
    
         
            +
                      AppRunner.stop_app(app.id)
         
     | 
| 
      
 22 
     | 
    
         
            +
                      AppRunner.start_app(app)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    elsif environment_changed?(app)
         
     | 
| 
      
 24 
     | 
    
         
            +
                      log_info("[#{app.name}] Environment changed, restarting...")
         
     | 
| 
      
 25 
     | 
    
         
            +
                      AppRunner.stop_app(app.id)
         
     | 
| 
      
 26 
     | 
    
         
            +
                      AppRunner.start_app(app)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    else
         
     | 
| 
      
 28 
     | 
    
         
            +
                      sync_dispatcher_count(app)
         
     | 
| 
       21 
29 
     | 
    
         
             
                    end
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
                    sync_dispatcher_count(app)
         
     | 
| 
       24 
30 
     | 
    
         
             
                  end
         
     | 
| 
       25 
31 
     | 
    
         | 
| 
       26 
32 
     | 
    
         
             
                  def self.sync_dispatcher_count(app)
         
     | 
| 
         @@ -39,6 +45,16 @@ module Rpush 
     | 
|
| 
       39 
45 
     | 
    
         
             
                    num_dispatchers = AppRunner.num_dispatchers_for_app(app)
         
     | 
| 
       40 
46 
     | 
    
         
             
                    log_info("[#{app.name}] #{start_stop_str} #{pluralize(diff.abs, 'dispatcher')}. #{num_dispatchers} running.")
         
     | 
| 
       41 
47 
     | 
    
         
             
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                  def self.certificate_changed?(app)
         
     | 
| 
      
 50 
     | 
    
         
            +
                    old_app = AppRunner.app_with_id(app.id)
         
     | 
| 
      
 51 
     | 
    
         
            +
                    app.certificate != old_app.certificate
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                  def self.environment_changed?(app)
         
     | 
| 
      
 55 
     | 
    
         
            +
                    old_app = AppRunner.app_with_id(app.id)
         
     | 
| 
      
 56 
     | 
    
         
            +
                    app.environment != old_app.environment
         
     | 
| 
      
 57 
     | 
    
         
            +
                  end
         
     | 
| 
       42 
58 
     | 
    
         
             
                end
         
     | 
| 
       43 
59 
     | 
    
         
             
              end
         
     | 
| 
       44 
60 
     | 
    
         
             
            end
         
     | 
| 
         @@ -108,6 +108,12 @@ module Rpush 
     | 
|
| 
       108 
108 
     | 
    
         
             
                    ssl_socket.sync = true
         
     | 
| 
       109 
109 
     | 
    
         
             
                    ssl_socket.connect
         
     | 
| 
       110 
110 
     | 
    
         
             
                    [tcp_socket, ssl_socket]
         
     | 
| 
      
 111 
     | 
    
         
            +
                  rescue StandardError => error
         
     | 
| 
      
 112 
     | 
    
         
            +
                    if error.message =~ /certificate revoked/i
         
     | 
| 
      
 113 
     | 
    
         
            +
                      log_warn('Certificate has been revoked.')
         
     | 
| 
      
 114 
     | 
    
         
            +
                      reflect(:ssl_certificate_revoked, @app, error)
         
     | 
| 
      
 115 
     | 
    
         
            +
                    end
         
     | 
| 
      
 116 
     | 
    
         
            +
                    raise
         
     | 
| 
       111 
117 
     | 
    
         
             
                  end
         
     | 
| 
       112 
118 
     | 
    
         | 
| 
       113 
119 
     | 
    
         
             
                  def check_certificate_expiration
         
     | 
    
        data/lib/rpush/reflection.rb
    CHANGED
    
    | 
         @@ -15,7 +15,7 @@ module Rpush 
     | 
|
| 
       15 
15 
     | 
    
         
             
                  :notification_failed, :notification_will_retry, :gcm_delivered_to_recipient,
         
     | 
| 
       16 
16 
     | 
    
         
             
                  :gcm_failed_to_recipient, :gcm_canonical_id, :gcm_invalid_registration_id,
         
     | 
| 
       17 
17 
     | 
    
         
             
                  :error, :adm_canonical_id, :adm_failed_to_recipient,
         
     | 
| 
       18 
     | 
    
         
            -
                  :tcp_connection_lost, :ssl_certificate_will_expire,
         
     | 
| 
      
 18 
     | 
    
         
            +
                  :tcp_connection_lost, :ssl_certificate_will_expire, :ssl_certificate_revoked,
         
     | 
| 
       19 
19 
     | 
    
         
             
                  :notification_id_will_retry, :notification_id_failed
         
     | 
| 
       20 
20 
     | 
    
         
             
                ]
         
     | 
| 
       21 
21 
     | 
    
         | 
    
        data/lib/rpush/version.rb
    CHANGED
    
    
| 
         @@ -127,17 +127,16 @@ describe 'APNs' do 
     | 
|
| 
       127 
127 
     | 
    
         
             
                    notification1.delivered.should be_true
         
     | 
| 
       128 
128 
     | 
    
         
             
                  end
         
     | 
| 
       129 
129 
     | 
    
         | 
| 
       130 
     | 
    
         
            -
                  it 'marks notifications following the failed one as retryable'  
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
       133 
     | 
    
         
            -
             
     | 
| 
       134 
     | 
    
         
            -
             
     | 
| 
       135 
     | 
    
         
            -
             
     | 
| 
       136 
     | 
    
         
            -
             
     | 
| 
       137 
     | 
    
         
            -
             
     | 
| 
       138 
     | 
    
         
            -
             
     | 
| 
       139 
     | 
    
         
            -
                   
     | 
| 
       140 
     | 
    
         
            -
                  # end
         
     | 
| 
      
 130 
     | 
    
         
            +
                  it 'marks notifications following the failed one as retryable' do
         
     | 
| 
      
 131 
     | 
    
         
            +
                    Rpush.config.push_poll = 1_000_000
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
                    notifications.each { |n| wait_for_notification_to_deliver(n) }
         
     | 
| 
      
 134 
     | 
    
         
            +
                    fail_notification(notification2)
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
                    [notification3, notification4].each do |n|
         
     | 
| 
      
 137 
     | 
    
         
            +
                      wait_for_notification_to_retry(n)
         
     | 
| 
      
 138 
     | 
    
         
            +
                    end
         
     | 
| 
      
 139 
     | 
    
         
            +
                  end
         
     | 
| 
       141 
140 
     | 
    
         | 
| 
       142 
141 
     | 
    
         
             
                  describe 'without an error response' do
         
     | 
| 
       143 
142 
     | 
    
         
             
                    it 'marks all notifications as failed' do
         
     | 
| 
         @@ -16,6 +16,9 @@ describe 'Synchronization' do 
     | 
|
| 
       16 
16 
     | 
    
         
             
                app.name = 'test'
         
     | 
| 
       17 
17 
     | 
    
         
             
                app.auth_key = 'abc123'
         
     | 
| 
       18 
18 
     | 
    
         
             
                app.connections = 2
         
     | 
| 
      
 19 
     | 
    
         
            +
                app.certificate = TEST_CERT_WITH_PASSWORD
         
     | 
| 
      
 20 
     | 
    
         
            +
                app.password = 'fubar'
         
     | 
| 
      
 21 
     | 
    
         
            +
                app.environment = 'sandbox'
         
     | 
| 
       19 
22 
     | 
    
         
             
                app.save!
         
     | 
| 
       20 
23 
     | 
    
         | 
| 
       21 
24 
     | 
    
         
             
                Rpush.embed
         
     | 
| 
         @@ -43,4 +46,23 @@ describe 'Synchronization' do 
     | 
|
| 
       43 
46 
     | 
    
         
             
                Rpush.sync
         
     | 
| 
       44 
47 
     | 
    
         
             
                Rpush::Daemon::AppRunner.app_running?(app).should be_false
         
     | 
| 
       45 
48 
     | 
    
         
             
              end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
              it 'restarts an app when the certificate is changed' do
         
     | 
| 
      
 51 
     | 
    
         
            +
                app.certificate = TEST_CERT
         
     | 
| 
      
 52 
     | 
    
         
            +
                app.password = nil
         
     | 
| 
      
 53 
     | 
    
         
            +
                app.save!
         
     | 
| 
      
 54 
     | 
    
         
            +
                Rpush.sync
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                running_app = Rpush::Daemon::AppRunner.app_with_id(app.id)
         
     | 
| 
      
 57 
     | 
    
         
            +
                expect(running_app.certificate).to eql(TEST_CERT)
         
     | 
| 
      
 58 
     | 
    
         
            +
              end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
              it 'restarts an app when the environment is changed' do
         
     | 
| 
      
 61 
     | 
    
         
            +
                app.environment = 'production'
         
     | 
| 
      
 62 
     | 
    
         
            +
                app.save!
         
     | 
| 
      
 63 
     | 
    
         
            +
                Rpush.sync
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                running_app = Rpush::Daemon::AppRunner.app_with_id(app.id)
         
     | 
| 
      
 66 
     | 
    
         
            +
                expect(running_app.environment).to eql('production')
         
     | 
| 
      
 67 
     | 
    
         
            +
              end
         
     | 
| 
       46 
68 
     | 
    
         
             
            end
         
     | 
| 
         @@ -32,7 +32,7 @@ module Rpush 
     | 
|
| 
       32 
32 
     | 
    
         
             
            end
         
     | 
| 
       33 
33 
     | 
    
         | 
| 
       34 
34 
     | 
    
         
             
            describe Rpush::Daemon::AppRunner, 'enqueue' do
         
     | 
| 
       35 
     | 
    
         
            -
              let(:app) { double(id: 1) }
         
     | 
| 
      
 35 
     | 
    
         
            +
              let(:app) { double(id: 1, name: 'Test', connections: 1) }
         
     | 
| 
       36 
36 
     | 
    
         
             
              let(:notification) { double(app_id: 1) }
         
     | 
| 
       37 
37 
     | 
    
         
             
              let(:runner) { double(Rpush::Daemon::AppRunner, enqueue: nil, start: nil, stop: nil) }
         
     | 
| 
       38 
38 
     | 
    
         
             
              let(:logger) { double(Rpush::Logger, error: nil, info: nil) }
         
     | 
| 
         @@ -53,7 +53,7 @@ describe Rpush::Daemon::AppRunner, 'enqueue' do 
     | 
|
| 
       53 
53 
     | 
    
         | 
| 
       54 
54 
     | 
    
         
             
              it 'starts the app if a runner does not exist' do
         
     | 
| 
       55 
55 
     | 
    
         
             
                notification = double(app_id: 3)
         
     | 
| 
       56 
     | 
    
         
            -
                new_app = double(Rpush::App, id: 3)
         
     | 
| 
      
 56 
     | 
    
         
            +
                new_app = double(Rpush::App, id: 3, name: 'NewApp', connections: 1)
         
     | 
| 
       57 
57 
     | 
    
         
             
                Rpush::Daemon.store = double(app: new_app)
         
     | 
| 
       58 
58 
     | 
    
         
             
                Rpush::Daemon::AppRunner.enqueue([notification])
         
     | 
| 
       59 
59 
     | 
    
         
             
                Rpush::Daemon::AppRunner.app_running?(new_app).should be_true
         
     | 
| 
         @@ -69,4 +69,27 @@ describe Rpush::Daemon::SignalHandler do 
     | 
|
| 
       69 
69 
     | 
    
         
             
                  end
         
     | 
| 
       70 
70 
     | 
    
         
             
                end
         
     | 
| 
       71 
71 
     | 
    
         
             
              end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
              describe 'error handing' do
         
     | 
| 
      
 74 
     | 
    
         
            +
                let(:error) { StandardError.new('test') }
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                before { Rpush.stub(logger: double(error: nil)) }
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                it 'logs errors received when handling a signal' do
         
     | 
| 
      
 79 
     | 
    
         
            +
                  Rpush::Daemon::Synchronizer.stub(:sync).and_raise(error)
         
     | 
| 
      
 80 
     | 
    
         
            +
                  expect(Rpush.logger).to receive(:error).with(error)
         
     | 
| 
      
 81 
     | 
    
         
            +
                  with_handler_start_stop do
         
     | 
| 
      
 82 
     | 
    
         
            +
                    signal_handler('HUP')
         
     | 
| 
      
 83 
     | 
    
         
            +
                  end
         
     | 
| 
      
 84 
     | 
    
         
            +
                end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                it 'does not interrupt processing of further errors' do
         
     | 
| 
      
 87 
     | 
    
         
            +
                  Rpush::Daemon::Synchronizer.stub(:sync).and_raise(error)
         
     | 
| 
      
 88 
     | 
    
         
            +
                  expect(Rpush::Daemon::AppRunner).to receive(:debug)
         
     | 
| 
      
 89 
     | 
    
         
            +
                  with_handler_start_stop do
         
     | 
| 
      
 90 
     | 
    
         
            +
                    signal_handler('HUP')
         
     | 
| 
      
 91 
     | 
    
         
            +
                    signal_handler('USR2')
         
     | 
| 
      
 92 
     | 
    
         
            +
                  end
         
     | 
| 
      
 93 
     | 
    
         
            +
                end
         
     | 
| 
      
 94 
     | 
    
         
            +
              end
         
     | 
| 
       72 
95 
     | 
    
         
             
            end
         
     | 
| 
         @@ -113,6 +113,23 @@ describe Rpush::Daemon::TcpConnection do 
     | 
|
| 
       113 
113 
     | 
    
         
             
                    end
         
     | 
| 
       114 
114 
     | 
    
         
             
                  end
         
     | 
| 
       115 
115 
     | 
    
         
             
                end
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
                describe 'certificate revocation' do
         
     | 
| 
      
 118 
     | 
    
         
            +
                  let(:cert_revoked_error) { OpenSSL::SSL::SSLError.new('certificate revoked') }
         
     | 
| 
      
 119 
     | 
    
         
            +
                  before do
         
     | 
| 
      
 120 
     | 
    
         
            +
                    ssl_socket.stub(:connect).and_raise(cert_revoked_error)
         
     | 
| 
      
 121 
     | 
    
         
            +
                  end
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
                  it 'reflects that the certificate has been revoked' do
         
     | 
| 
      
 124 
     | 
    
         
            +
                    connection.should_receive(:reflect).with(:ssl_certificate_revoked, app, cert_revoked_error)
         
     | 
| 
      
 125 
     | 
    
         
            +
                    expect { connection.connect }.to raise_error(cert_revoked_error)
         
     | 
| 
      
 126 
     | 
    
         
            +
                  end
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
                  it 'logs that the certificate has been revoked' do
         
     | 
| 
      
 129 
     | 
    
         
            +
                    logger.should_receive(:warn).with('[Connection 0] Certificate has been revoked.')
         
     | 
| 
      
 130 
     | 
    
         
            +
                    expect { connection.connect }.to raise_error(cert_revoked_error)
         
     | 
| 
      
 131 
     | 
    
         
            +
                  end
         
     | 
| 
      
 132 
     | 
    
         
            +
                end
         
     | 
| 
       116 
133 
     | 
    
         
             
              end
         
     | 
| 
       117 
134 
     | 
    
         | 
| 
       118 
135 
     | 
    
         
             
              describe "when shuting down the connection" do
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: rpush
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 2.0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 2.0.1
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: java
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Ian Leitch
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire:
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2014-09- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2014-09-13 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: multi_json
         
     | 
| 
         @@ -277,9 +277,9 @@ required_ruby_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       277 
277 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       278 
278 
     | 
    
         
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
       279 
279 
     | 
    
         
             
              requirements:
         
     | 
| 
       280 
     | 
    
         
            -
              - - ' 
     | 
| 
      
 280 
     | 
    
         
            +
              - - '>='
         
     | 
| 
       281 
281 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       282 
     | 
    
         
            -
                  version:  
     | 
| 
      
 282 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
       283 
283 
     | 
    
         
             
            requirements: []
         
     | 
| 
       284 
284 
     | 
    
         
             
            rubyforge_project:
         
     | 
| 
       285 
285 
     | 
    
         
             
            rubygems_version: 2.1.9
         
     |