rpush 1.0.0 → 2.0.0.beta1

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.
Files changed (193) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -0
  3. data/README.md +12 -14
  4. data/bin/rpush +11 -2
  5. data/lib/generators/rpush_generator.rb +2 -0
  6. data/lib/generators/templates/add_adm.rb +5 -5
  7. data/lib/generators/templates/add_alert_is_json_to_rapns_notifications.rb +1 -1
  8. data/lib/generators/templates/add_app_to_rapns.rb +2 -2
  9. data/lib/generators/templates/add_fail_after_to_rpush_notifications.rb +1 -1
  10. data/lib/generators/templates/add_gcm.rb +32 -32
  11. data/lib/generators/templates/add_rpush.rb +67 -67
  12. data/lib/generators/templates/add_wpns.rb +2 -2
  13. data/lib/generators/templates/create_rapns_apps.rb +5 -5
  14. data/lib/generators/templates/create_rapns_feedback.rb +2 -2
  15. data/lib/generators/templates/create_rapns_notifications.rb +15 -15
  16. data/lib/generators/templates/rpush.rb +10 -7
  17. data/lib/generators/templates/rpush_2_0_0_updates.rb +23 -0
  18. data/lib/rpush.rb +4 -28
  19. data/lib/rpush/client/active_model.rb +21 -0
  20. data/lib/rpush/client/active_model/adm/app.rb +23 -0
  21. data/lib/rpush/client/active_model/adm/data_validator.rb +14 -0
  22. data/lib/rpush/client/active_model/adm/notification.rb +28 -0
  23. data/lib/rpush/client/active_model/apns/app.rb +37 -0
  24. data/lib/rpush/client/active_model/apns/binary_notification_validator.rb +16 -0
  25. data/lib/rpush/client/active_model/apns/device_token_format_validator.rb +14 -0
  26. data/lib/rpush/client/active_model/apns/notification.rb +90 -0
  27. data/lib/rpush/client/active_model/gcm/app.rb +19 -0
  28. data/lib/rpush/client/active_model/gcm/expiry_collapse_key_mutual_inclusion_validator.rb +14 -0
  29. data/lib/rpush/client/active_model/gcm/notification.rb +31 -0
  30. data/lib/rpush/client/active_model/notification.rb +26 -0
  31. data/lib/rpush/client/active_model/payload_data_size_validator.rb +13 -0
  32. data/lib/rpush/client/active_model/registration_ids_count_validator.rb +13 -0
  33. data/lib/rpush/client/active_model/wpns/app.rb +13 -0
  34. data/lib/rpush/client/active_model/wpns/notification.rb +17 -0
  35. data/lib/rpush/client/active_record.rb +19 -0
  36. data/lib/rpush/client/active_record/adm/app.rb +11 -0
  37. data/lib/rpush/client/active_record/adm/notification.rb +11 -0
  38. data/lib/rpush/client/active_record/apns/app.rb +11 -0
  39. data/lib/rpush/client/active_record/apns/feedback.rb +20 -0
  40. data/lib/rpush/client/active_record/apns/notification.rb +46 -0
  41. data/lib/rpush/client/active_record/app.rb +17 -0
  42. data/lib/rpush/client/active_record/gcm/app.rb +11 -0
  43. data/lib/rpush/client/active_record/gcm/notification.rb +11 -0
  44. data/lib/rpush/client/active_record/notification.rb +38 -0
  45. data/lib/rpush/client/active_record/wpns/app.rb +11 -0
  46. data/lib/rpush/client/active_record/wpns/notification.rb +11 -0
  47. data/lib/rpush/client/redis.rb +35 -0
  48. data/lib/rpush/client/redis/adm/app.rb +14 -0
  49. data/lib/rpush/client/redis/adm/notification.rb +11 -0
  50. data/lib/rpush/client/redis/apns/app.rb +11 -0
  51. data/lib/rpush/client/redis/apns/feedback.rb +20 -0
  52. data/lib/rpush/client/redis/apns/notification.rb +11 -0
  53. data/lib/rpush/client/redis/app.rb +22 -0
  54. data/lib/rpush/client/redis/gcm/app.rb +11 -0
  55. data/lib/rpush/client/redis/gcm/notification.rb +11 -0
  56. data/lib/rpush/client/redis/notification.rb +68 -0
  57. data/lib/rpush/client/redis/wpns/app.rb +11 -0
  58. data/lib/rpush/client/redis/wpns/notification.rb +11 -0
  59. data/lib/rpush/configuration.rb +27 -6
  60. data/lib/rpush/daemon.rb +36 -56
  61. data/lib/rpush/daemon/adm/delivery.rb +50 -52
  62. data/lib/rpush/daemon/apns.rb +6 -5
  63. data/lib/rpush/daemon/apns/delivery.rb +20 -44
  64. data/lib/rpush/daemon/apns/feedback_receiver.rb +11 -8
  65. data/lib/rpush/daemon/app_runner.rb +67 -60
  66. data/lib/rpush/daemon/batch.rb +54 -40
  67. data/lib/rpush/daemon/delivery.rb +13 -3
  68. data/lib/rpush/daemon/delivery_error.rb +10 -2
  69. data/lib/rpush/daemon/dispatcher/apns_tcp.rb +106 -0
  70. data/lib/rpush/daemon/dispatcher/http.rb +3 -3
  71. data/lib/rpush/daemon/dispatcher/tcp.rb +3 -3
  72. data/lib/rpush/daemon/dispatcher_loop.rb +15 -6
  73. data/lib/rpush/daemon/errors.rb +18 -0
  74. data/lib/rpush/daemon/feeder.rb +28 -39
  75. data/lib/rpush/daemon/gcm/delivery.rb +19 -20
  76. data/lib/rpush/daemon/interruptible_sleep.rb +26 -45
  77. data/lib/rpush/daemon/loggable.rb +2 -4
  78. data/lib/rpush/daemon/proc_title.rb +16 -0
  79. data/lib/rpush/daemon/queue_payload.rb +12 -0
  80. data/lib/rpush/daemon/reflectable.rb +3 -5
  81. data/lib/rpush/daemon/retry_header_parser.rb +6 -6
  82. data/lib/rpush/daemon/ring_buffer.rb +16 -0
  83. data/lib/rpush/daemon/service_config_methods.rb +23 -7
  84. data/lib/rpush/daemon/signal_handler.rb +51 -0
  85. data/lib/rpush/daemon/store/active_record.rb +71 -38
  86. data/lib/rpush/daemon/store/active_record/reconnectable.rb +15 -15
  87. data/lib/rpush/daemon/store/interface.rb +19 -0
  88. data/lib/rpush/daemon/store/redis.rb +149 -0
  89. data/lib/rpush/daemon/tcp_connection.rb +6 -11
  90. data/lib/rpush/daemon/wpns/delivery.rb +21 -30
  91. data/lib/rpush/deprecatable.rb +4 -3
  92. data/lib/rpush/deprecation.rb +7 -10
  93. data/lib/rpush/embed.rb +7 -2
  94. data/lib/rpush/logger.rb +11 -15
  95. data/lib/rpush/push.rb +0 -1
  96. data/lib/rpush/reflection.rb +6 -12
  97. data/lib/rpush/version.rb +1 -1
  98. data/lib/tasks/quality.rake +34 -0
  99. data/spec/.rubocop.yml +4 -0
  100. data/spec/functional/adm_spec.rb +3 -6
  101. data/spec/functional/apns_spec.rb +118 -24
  102. data/spec/functional/embed_spec.rb +22 -20
  103. data/spec/functional/gcm_spec.rb +4 -7
  104. data/spec/functional/new_app_spec.rb +61 -0
  105. data/spec/functional/retry_spec.rb +46 -0
  106. data/spec/functional/wpns_spec.rb +3 -6
  107. data/spec/functional_spec_helper.rb +26 -0
  108. data/spec/integration/rpush_spec.rb +13 -0
  109. data/spec/integration/support/gcm_success_response.json +1 -0
  110. data/spec/spec_helper.rb +60 -0
  111. data/spec/support/active_record_setup.rb +48 -0
  112. data/{config → spec/support/config}/database.yml +0 -0
  113. data/spec/support/install.sh +43 -7
  114. data/spec/support/simplecov_helper.rb +9 -5
  115. data/spec/support/simplecov_quality_formatter.rb +10 -6
  116. data/spec/unit/apns_feedback_spec.rb +3 -3
  117. data/spec/unit/{adm → client/active_record/adm}/app_spec.rb +3 -3
  118. data/spec/unit/{adm → client/active_record/adm}/notification_spec.rb +5 -7
  119. data/spec/unit/client/active_record/apns/app_spec.rb +29 -0
  120. data/spec/unit/client/active_record/apns/feedback_spec.rb +9 -0
  121. data/spec/unit/client/active_record/apns/notification_spec.rb +231 -0
  122. data/spec/unit/client/active_record/app_spec.rb +30 -0
  123. data/spec/unit/client/active_record/gcm/app_spec.rb +4 -0
  124. data/spec/unit/{gcm → client/active_record/gcm}/notification_spec.rb +5 -7
  125. data/spec/unit/client/active_record/notification_spec.rb +15 -0
  126. data/spec/unit/client/active_record/wpns/app_spec.rb +4 -0
  127. data/spec/unit/client/active_record/wpns/notification_spec.rb +21 -0
  128. data/spec/unit/configuration_spec.rb +12 -5
  129. data/spec/unit/daemon/adm/delivery_spec.rb +57 -54
  130. data/spec/unit/daemon/apns/certificate_expired_error_spec.rb +3 -3
  131. data/spec/unit/daemon/apns/delivery_spec.rb +90 -83
  132. data/spec/unit/daemon/apns/feedback_receiver_spec.rb +24 -17
  133. data/spec/unit/daemon/app_runner_spec.rb +66 -123
  134. data/spec/unit/daemon/batch_spec.rb +52 -115
  135. data/spec/unit/daemon/delivery_spec.rb +15 -1
  136. data/spec/unit/daemon/dispatcher/http_spec.rb +3 -2
  137. data/spec/unit/daemon/dispatcher/tcp_spec.rb +10 -9
  138. data/spec/unit/daemon/dispatcher_loop_spec.rb +7 -12
  139. data/spec/unit/daemon/feeder_spec.rb +40 -39
  140. data/spec/unit/daemon/gcm/delivery_spec.rb +108 -89
  141. data/spec/unit/daemon/reflectable_spec.rb +2 -2
  142. data/spec/unit/daemon/retryable_error_spec.rb +1 -1
  143. data/spec/unit/daemon/service_config_methods_spec.rb +6 -3
  144. data/spec/unit/daemon/signal_handler_spec.rb +72 -0
  145. data/spec/unit/daemon/store/active_record/reconnectable_spec.rb +9 -9
  146. data/spec/unit/daemon/store/active_record_spec.rb +38 -47
  147. data/spec/unit/daemon/tcp_connection_spec.rb +22 -34
  148. data/spec/unit/daemon/too_many_requests_error_spec.rb +1 -1
  149. data/spec/unit/daemon/wpns/delivery_spec.rb +61 -50
  150. data/spec/unit/daemon_spec.rb +46 -81
  151. data/spec/unit/embed_spec.rb +4 -2
  152. data/spec/unit/logger_spec.rb +30 -40
  153. data/spec/unit/notification_shared.rb +9 -79
  154. data/spec/unit/push_spec.rb +3 -8
  155. data/spec/unit/reflection_spec.rb +25 -25
  156. data/spec/unit/rpush_spec.rb +1 -2
  157. data/spec/unit_spec_helper.rb +33 -88
  158. metadata +119 -67
  159. data/lib/rpush/TODO +0 -3
  160. data/lib/rpush/adm/app.rb +0 -15
  161. data/lib/rpush/adm/data_validator.rb +0 -11
  162. data/lib/rpush/adm/notification.rb +0 -29
  163. data/lib/rpush/apns/app.rb +0 -29
  164. data/lib/rpush/apns/binary_notification_validator.rb +0 -12
  165. data/lib/rpush/apns/device_token_format_validator.rb +0 -12
  166. data/lib/rpush/apns/feedback.rb +0 -16
  167. data/lib/rpush/apns/notification.rb +0 -84
  168. data/lib/rpush/app.rb +0 -18
  169. data/lib/rpush/daemon/apns/certificate_expired_error.rb +0 -20
  170. data/lib/rpush/daemon/apns/disconnection_error.rb +0 -20
  171. data/lib/rpush/gcm/app.rb +0 -11
  172. data/lib/rpush/gcm/expiry_collapse_key_mutual_inclusion_validator.rb +0 -11
  173. data/lib/rpush/gcm/notification.rb +0 -30
  174. data/lib/rpush/notification.rb +0 -69
  175. data/lib/rpush/notifier.rb +0 -52
  176. data/lib/rpush/payload_data_size_validator.rb +0 -10
  177. data/lib/rpush/railtie.rb +0 -11
  178. data/lib/rpush/registration_ids_count_validator.rb +0 -10
  179. data/lib/rpush/wpns/app.rb +0 -9
  180. data/lib/rpush/wpns/notification.rb +0 -26
  181. data/lib/tasks/cane.rake +0 -18
  182. data/lib/tasks/rpush.rake +0 -16
  183. data/spec/unit/apns/app_spec.rb +0 -29
  184. data/spec/unit/apns/feedback_spec.rb +0 -9
  185. data/spec/unit/apns/notification_spec.rb +0 -208
  186. data/spec/unit/app_spec.rb +0 -30
  187. data/spec/unit/daemon/apns/disconnection_error_spec.rb +0 -18
  188. data/spec/unit/daemon/interruptible_sleep_spec.rb +0 -68
  189. data/spec/unit/gcm/app_spec.rb +0 -4
  190. data/spec/unit/notification_spec.rb +0 -15
  191. data/spec/unit/notifier_spec.rb +0 -49
  192. data/spec/unit/wpns/app_spec.rb +0 -4
  193. data/spec/unit/wpns/notification_spec.rb +0 -30
@@ -13,15 +13,25 @@ module Rpush
13
13
  end
14
14
 
15
15
  def mark_retryable_exponential(notification)
16
- mark_retryable(notification, Time.now + 2 ** (notification.retries + 1))
16
+ mark_retryable(notification, Time.now + 2**(notification.retries + 1))
17
17
  end
18
18
 
19
19
  def mark_delivered
20
20
  @batch.mark_delivered(@notification)
21
21
  end
22
22
 
23
- def mark_failed(code, description)
24
- @batch.mark_failed(@notification, code, description)
23
+ def mark_batch_delivered
24
+ @batch.mark_all_delivered
25
+ end
26
+
27
+ def mark_failed(error)
28
+ code = error.respond_to?(:code) ? error.code : nil
29
+ @batch.mark_failed(@notification, code, error.to_s)
30
+ end
31
+
32
+ def mark_batch_failed(error)
33
+ code = error.respond_to?(:code) ? error.code : nil
34
+ @batch.mark_all_failed(code, error.to_s)
25
35
  end
26
36
  end
27
37
  end
@@ -1,6 +1,6 @@
1
1
  module Rpush
2
2
  class DeliveryError < StandardError
3
- attr_reader :code, :description
3
+ attr_reader :code, :notification_id
4
4
 
5
5
  def initialize(code, notification_id, description)
6
6
  @code = code
@@ -13,7 +13,15 @@ module Rpush
13
13
  end
14
14
 
15
15
  def message
16
- "Unable to deliver notification #{@notification_id}, received error #{@code} (#{@description})"
16
+ error_str = [@code, "(#{@description})"].compact.join(' ')
17
+ "Unable to deliver notification #{@notification_id}, received error #{error_str}"
18
+ end
19
+
20
+ def ==(other)
21
+ other.is_a?(DeliveryError) && \
22
+ other.code == code && \
23
+ other.notification_id == notification_id && \
24
+ other.to_s == to_s
17
25
  end
18
26
  end
19
27
  end
@@ -0,0 +1,106 @@
1
+ module Rpush
2
+ module Daemon
3
+ module Dispatcher
4
+ class ApnsTcp < Rpush::Daemon::Dispatcher::Tcp
5
+ include Loggable
6
+
7
+ SELECT_TIMEOUT = 10
8
+ ERROR_TUPLE_BYTES = 6
9
+ APNS_ERRORS = {
10
+ 1 => 'Processing error',
11
+ 2 => 'Missing device token',
12
+ 3 => 'Missing topic',
13
+ 4 => 'Missing payload',
14
+ 5 => 'Missing token size',
15
+ 6 => 'Missing topic size',
16
+ 7 => 'Missing payload size',
17
+ 8 => 'Invalid token',
18
+ 255 => 'None (unknown error)'
19
+ }
20
+
21
+ def initialize(*args)
22
+ super
23
+ @dispatch_mutex = Mutex.new
24
+ @stop_error_receiver = false
25
+ start_error_receiver
26
+ end
27
+
28
+ def dispatch(payload)
29
+ @dispatch_mutex.synchronize do
30
+ @delivery_class.new(@app, connection, payload.batch).perform
31
+ record_batch(payload.batch)
32
+ end
33
+ end
34
+
35
+ def cleanup
36
+ @stop_error_receiver = true
37
+ super
38
+ @error_receiver_thread.join if @error_receiver_thread
39
+ end
40
+
41
+ private
42
+
43
+ def start_error_receiver
44
+ @error_receiver_thread = Thread.new do
45
+ check_for_error until @stop_error_receiver
46
+ Rpush::Daemon.store.release_connection
47
+ end
48
+ end
49
+
50
+ def delivered_buffer
51
+ @delivered_buffer ||= RingBuffer.new(Rpush.config.batch_size * 10)
52
+ end
53
+
54
+ def record_batch(batch)
55
+ batch.each_delivered do |notification|
56
+ delivered_buffer << notification.id
57
+ end
58
+ end
59
+
60
+ def check_for_error
61
+ begin
62
+ return unless connection.select(SELECT_TIMEOUT)
63
+ rescue Errno::EBADF
64
+ # Connection closed, daemon is shutting down.
65
+ return
66
+ end
67
+
68
+ tuple = connection.read(ERROR_TUPLE_BYTES)
69
+ @dispatch_mutex.synchronize { handle_error_response(tuple) }
70
+ end
71
+
72
+ def handle_error_response(tuple)
73
+ if tuple
74
+ _, code, notification_id = tuple.unpack('ccN')
75
+ handle_error(code, notification_id)
76
+ else
77
+ handle_disconnect
78
+ end
79
+
80
+ log_error('Error received, reconnecting...')
81
+ connection.reconnect
82
+ ensure
83
+ delivered_buffer.clear
84
+ end
85
+
86
+ def handle_disconnect
87
+ log_error('The APNs disconnected without returning an error. Marking all notifications delivered via this connection as failed.')
88
+ Rpush::Daemon.store.mark_ids_failed(delivered_buffer, nil, 'The APNs disconnected without returning an error. This may indicate you are using an invalid certificate.', Time.now)
89
+ end
90
+
91
+ def handle_error(code, notification_id)
92
+ failed_pos = delivered_buffer.index(notification_id)
93
+ description = APNS_ERRORS[code.to_i] || "Unknown error code #{code.inspect}. Possible Rpush bug?"
94
+ Rpush::Daemon.store.mark_ids_failed([notification_id], code, description, Time.now)
95
+
96
+ if failed_pos
97
+ retry_ids = delivered_buffer[(failed_pos + 1)..-1]
98
+ Rpush::Daemon.store.mark_ids_retryable(retry_ids, Time.now) if retry_ids.size > 0
99
+ elsif delivered_buffer.size > 0
100
+ log_error("Delivery sequence unknown for notifications following #{notification_id}.")
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
@@ -2,14 +2,14 @@ module Rpush
2
2
  module Daemon
3
3
  module Dispatcher
4
4
  class Http
5
- def initialize(app, delivery_class, options = {})
5
+ def initialize(app, delivery_class, _options = {})
6
6
  @app = app
7
7
  @delivery_class = delivery_class
8
8
  @http = Net::HTTP::Persistent.new('rpush')
9
9
  end
10
10
 
11
- def dispatch(notification, batch)
12
- @delivery_class.new(@app, @http, notification, batch).perform
11
+ def dispatch(payload)
12
+ @delivery_class.new(@app, @http, payload.notification, payload.batch).perform
13
13
  end
14
14
 
15
15
  def cleanup
@@ -8,15 +8,15 @@ module Rpush
8
8
  @host, @port = options[:host].call(@app)
9
9
  end
10
10
 
11
- def dispatch(notification, batch)
12
- @delivery_class.new(@app, connection, notification, batch).perform
11
+ def dispatch(payload)
12
+ @delivery_class.new(@app, connection, payload.notification, payload.batch).perform
13
13
  end
14
14
 
15
15
  def cleanup
16
16
  @connection.close if @connection
17
17
  end
18
18
 
19
- private
19
+ protected
20
20
 
21
21
  def connection
22
22
  return @connection if defined? @connection
@@ -2,15 +2,25 @@ module Rpush
2
2
  module Daemon
3
3
  class DispatcherLoop
4
4
  include Reflectable
5
+ include Loggable
6
+
7
+ attr_reader :started_at, :dispatch_count
5
8
 
6
9
  WAKEUP = :wakeup
7
10
 
8
11
  def initialize(queue, dispatcher)
9
12
  @queue = queue
10
13
  @dispatcher = dispatcher
14
+ @dispatch_count = 0
15
+ end
16
+
17
+ def thread_status
18
+ @thread ? @thread.status : 'not started'
11
19
  end
12
20
 
13
21
  def start
22
+ @started_at = Time.now
23
+
14
24
  @thread = Thread.new do
15
25
  loop do
16
26
  dispatch
@@ -37,16 +47,15 @@ module Rpush
37
47
  protected
38
48
 
39
49
  def dispatch
40
- notification, batch = @queue.pop
41
- return if notification == WAKEUP
50
+ payload = @queue.pop
51
+ return if payload == WAKEUP
42
52
 
43
53
  begin
44
- @dispatcher.dispatch(notification, batch)
54
+ @dispatch_count += 1
55
+ @dispatcher.dispatch(payload)
45
56
  rescue StandardError => e
46
- Rpush.logger.error(e)
57
+ log_error(e)
47
58
  reflect(:error, e)
48
- ensure
49
- batch.notification_dispatched
50
59
  end
51
60
  end
52
61
  end
@@ -0,0 +1,18 @@
1
+ module Rpush
2
+ class CertificateExpiredError < StandardError
3
+ attr_reader :app, :time
4
+
5
+ def initialize(app, time)
6
+ @app = app
7
+ @time = time
8
+ end
9
+
10
+ def to_s
11
+ message
12
+ end
13
+
14
+ def message
15
+ "#{app.name} certificate expired at #{time}."
16
+ end
17
+ end
18
+ end
@@ -4,63 +4,52 @@ module Rpush
4
4
  extend Reflectable
5
5
 
6
6
  def self.start
7
- @stop = false
8
-
9
- if Rpush.config.embedded
10
- Thread.new { feed_forever }
11
- elsif Rpush.config.push
12
- enqueue_notifications
13
- else
14
- feed_forever
15
- end
7
+ self.should_stop = false
8
+ Rpush.config.push ? enqueue_notifications : feed_forever
16
9
  end
17
10
 
18
11
  def self.stop
19
- @stop = true
20
- interrupt_sleep
12
+ self.should_stop = true
13
+ interruptible_sleeper.stop
14
+ @thread.join if @thread
21
15
  end
22
16
 
23
- def self.interrupt_sleep
24
- interruptible_sleeper.interrupt_sleep
17
+ def self.wakeup
18
+ interruptible_sleeper.wakeup
25
19
  end
26
20
 
27
- protected
21
+ class << self
22
+ attr_accessor :should_stop
23
+ end
28
24
 
29
25
  def self.feed_forever
30
- loop do
31
- enqueue_notifications
32
- interruptible_sleeper.sleep(Rpush.config.push_poll)
33
- break if stop?
26
+ @thread = Thread.new do
27
+ loop do
28
+ enqueue_notifications
29
+ interruptible_sleeper.sleep
30
+ break if should_stop
31
+ end
32
+
33
+ Rpush::Daemon.store.release_connection
34
34
  end
35
35
 
36
- Rpush::Daemon.store.release_connection
37
- end
38
-
39
- # :nocov:
40
- def self.stop?
41
- @stop
36
+ @thread.join
42
37
  end
43
38
 
44
39
  def self.enqueue_notifications
45
- begin
46
- idle = Rpush::Daemon::AppRunner.idle.map(&:app)
47
- return if idle.empty?
48
- notifications = Rpush::Daemon.store.deliverable_notifications(idle)
49
- Rpush::Daemon::AppRunner.enqueue(notifications)
50
- rescue StandardError => e
51
- Rpush.logger.error(e)
52
- reflect(:error, e)
53
- end
40
+ batch_size = Rpush.config.batch_size - Rpush::Daemon::AppRunner.num_queued
41
+ return if batch_size <= 0
42
+ notifications = Rpush::Daemon.store.deliverable_notifications(batch_size)
43
+ Rpush::Daemon::AppRunner.enqueue(notifications)
44
+ rescue StandardError => e
45
+ Rpush.logger.error(e)
46
+ reflect(:error, e)
54
47
  end
55
48
 
56
49
  def self.interruptible_sleeper
57
50
  return @interruptible_sleeper if @interruptible_sleeper
58
-
59
- @interruptible_sleeper = InterruptibleSleep.new
60
- if Rpush.config.wakeup
61
- @interruptible_sleeper.enable_wake_on_udp Rpush.config.wakeup[:bind], Rpush.config.wakeup[:port]
62
- end
63
-
51
+ @interruptible_sleeper = InterruptibleSleep.new(Rpush.config.push_poll)
52
+ @interruptible_sleeper.start
64
53
  @interruptible_sleeper
65
54
  end
66
55
  end
@@ -1,15 +1,14 @@
1
1
  module Rpush
2
2
  module Daemon
3
3
  module Gcm
4
-
5
4
  # http://developer.android.com/guide/google/gcm/gcm.html#response
6
5
  class Delivery < Rpush::Daemon::Delivery
7
6
  include MultiJsonHelper
8
7
 
9
8
  host = ENV["RPUSH_GCM_HOST"] || "https://android.googleapis.com"
10
9
  GCM_URI = URI.parse("#{host}/gcm/send")
11
- UNAVAILABLE_STATES = ['Unavailable', 'InternalServerError']
12
- INVALID_REGISTRATION_ID_STATES = ['InvalidRegistration', 'MismatchSenderId', 'NotRegistered', 'InvalidPackageName']
10
+ UNAVAILABLE_STATES = %w(Unavailable InternalServerError)
11
+ INVALID_REGISTRATION_ID_STATES = %w(InvalidRegistration MismatchSenderId NotRegistered InvalidPackageName)
13
12
 
14
13
  def initialize(app, http, notification, batch)
15
14
  @app = app
@@ -19,12 +18,12 @@ module Rpush
19
18
  end
20
19
 
21
20
  def perform
22
- begin
23
- handle_response(do_post)
24
- rescue Rpush::DeliveryError => error
25
- mark_failed(error.code, error.description)
26
- raise
27
- end
21
+ handle_response(do_post)
22
+ rescue StandardError => error
23
+ mark_failed(error)
24
+ raise
25
+ ensure
26
+ @batch.notification_processed
28
27
  end
29
28
 
30
29
  protected
@@ -42,7 +41,7 @@ module Rpush
42
41
  when 503
43
42
  service_unavailable(response)
44
43
  else
45
- raise Rpush::DeliveryError.new(response.code, @notification.id, Rpush::Daemon::HTTP_STATUS_CODES[response.code.to_i])
44
+ fail Rpush::DeliveryError.new(response.code, @notification.id, Rpush::Daemon::HTTP_STATUS_CODES[response.code.to_i])
46
45
  end
47
46
  end
48
47
 
@@ -69,9 +68,8 @@ module Rpush
69
68
  def handle_successes(successes)
70
69
  successes.each do |result|
71
70
  reflect(:gcm_delivered_to_recipient, @notification, result[:registration_id])
72
- if result.has_key?(:canonical_id)
73
- reflect(:gcm_canonical_id, result[:registration_id], result[:canonical_id])
74
- end
71
+ next unless result.key?(:canonical_id)
72
+ reflect(:gcm_canonical_id, result[:registration_id], result[:canonical_id])
75
73
  end
76
74
  end
77
75
 
@@ -86,7 +84,7 @@ module Rpush
86
84
  failures.description += " #{unavailable_idxs.join(', ')} will be retried as notification #{new_notification.id}."
87
85
  end
88
86
  handle_errors(failures)
89
- raise Rpush::DeliveryError.new(nil, @notification.id, failures.description)
87
+ fail Rpush::DeliveryError.new(nil, @notification.id, failures.description)
90
88
  end
91
89
  end
92
90
 
@@ -103,15 +101,15 @@ module Rpush
103
101
  attrs = @notification.attributes.slice('app_id', 'collapse_key', 'delay_while_idle')
104
102
  registration_ids = @notification.registration_ids.values_at(*unavailable_idxs)
105
103
  Rpush::Daemon.store.create_gcm_notification(attrs, @notification.data,
106
- registration_ids, deliver_after_header(response), @notification.app)
104
+ registration_ids, deliver_after_header(response), @notification.app)
107
105
  end
108
106
 
109
107
  def bad_request
110
- raise Rpush::DeliveryError.new(400, @notification.id, 'GCM failed to parse the JSON request. Possibly an Rpush bug, please open an issue.')
108
+ fail Rpush::DeliveryError.new(400, @notification.id, 'GCM failed to parse the JSON request. Possibly an Rpush bug, please open an issue.')
111
109
  end
112
110
 
113
111
  def unauthorized
114
- raise Rpush::DeliveryError.new(401, @notification.id, 'Unauthorized, check your App auth_key.')
112
+ fail Rpush::DeliveryError.new(401, @notification.id, 'Unauthorized, check your App auth_key.')
115
113
  end
116
114
 
117
115
  def internal_server_error(response)
@@ -129,7 +127,8 @@ module Rpush
129
127
  end
130
128
 
131
129
  def retry_delivery(notification, response)
132
- if time = deliver_after_header(response)
130
+ time = deliver_after_header(response)
131
+ if time
133
132
  mark_retryable(notification, time)
134
133
  else
135
134
  mark_retryable_exponential(notification)
@@ -141,8 +140,8 @@ module Rpush
141
140
  end
142
141
 
143
142
  def do_post
144
- post = Net::HTTP::Post.new(GCM_URI.path, initheader = {'Content-Type' => 'application/json',
145
- 'Authorization' => "key=#{@notification.app.auth_key}"})
143
+ post = Net::HTTP::Post.new(GCM_URI.path, 'Content-Type' => 'application/json',
144
+ 'Authorization' => "key=#{@notification.app.auth_key}")
146
145
  post.body = @notification.as_json.to_json
147
146
  @http.request(GCM_URI, post)
148
147
  end