rpush 1.0.0 → 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
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