rpush 4.2.0 → 5.4.0

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 (121) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +248 -163
  3. data/README.md +103 -17
  4. data/lib/generators/templates/add_gcm.rb +4 -4
  5. data/lib/generators/templates/add_rpush.rb +4 -4
  6. data/lib/generators/templates/rpush.rb +4 -0
  7. data/lib/generators/templates/rpush_3_3_1_updates.rb +2 -2
  8. data/lib/rpush/cli.rb +1 -1
  9. data/lib/rpush/client/active_model.rb +4 -1
  10. data/lib/rpush/client/active_model/adm/data_validator.rb +1 -1
  11. data/lib/rpush/client/active_model/apns/device_token_format_validator.rb +2 -2
  12. data/lib/rpush/client/active_model/apns/notification.rb +9 -1
  13. data/lib/rpush/client/active_model/apns/notification_payload_size_validator.rb +15 -0
  14. data/lib/rpush/client/active_model/apns2/notification.rb +14 -0
  15. data/lib/rpush/client/active_model/gcm/expiry_collapse_key_mutual_inclusion_validator.rb +1 -1
  16. data/lib/rpush/client/active_model/gcm/notification.rb +2 -2
  17. data/lib/rpush/client/active_model/payload_data_size_validator.rb +1 -1
  18. data/lib/rpush/client/active_model/registration_ids_count_validator.rb +1 -1
  19. data/lib/rpush/client/active_model/webpush/app.rb +41 -0
  20. data/lib/rpush/client/active_model/webpush/notification.rb +66 -0
  21. data/lib/rpush/client/active_record.rb +4 -0
  22. data/lib/rpush/client/active_record/apns/active_record_serializable_notification.rb +65 -0
  23. data/lib/rpush/client/active_record/apns/notification.rb +1 -57
  24. data/lib/rpush/client/active_record/apns2/notification.rb +4 -1
  25. data/lib/rpush/client/active_record/apnsp8/notification.rb +1 -0
  26. data/lib/rpush/client/active_record/webpush/app.rb +11 -0
  27. data/lib/rpush/client/active_record/webpush/notification.rb +12 -0
  28. data/lib/rpush/client/redis.rb +3 -0
  29. data/lib/rpush/client/redis/apns2/notification.rb +1 -0
  30. data/lib/rpush/client/redis/apnsp8/notification.rb +2 -0
  31. data/lib/rpush/client/redis/pushy/notification.rb +0 -1
  32. data/lib/rpush/client/redis/webpush/app.rb +15 -0
  33. data/lib/rpush/client/redis/webpush/notification.rb +15 -0
  34. data/lib/rpush/configuration.rb +3 -2
  35. data/lib/rpush/daemon.rb +4 -1
  36. data/lib/rpush/daemon/apns/feedback_receiver.rb +1 -1
  37. data/lib/rpush/daemon/apns2/delivery.rb +13 -2
  38. data/lib/rpush/daemon/apnsp8/delivery.rb +7 -2
  39. data/lib/rpush/daemon/app_runner.rb +1 -1
  40. data/lib/rpush/daemon/batch.rb +12 -5
  41. data/lib/rpush/daemon/delivery.rb +1 -2
  42. data/lib/rpush/daemon/store/active_record/reconnectable.rb +1 -1
  43. data/lib/rpush/daemon/webpush.rb +10 -0
  44. data/lib/rpush/daemon/webpush/delivery.rb +114 -0
  45. data/lib/rpush/logger.rb +1 -0
  46. data/lib/rpush/version.rb +2 -2
  47. data/spec/functional/apns2_spec.rb +97 -2
  48. data/spec/functional/gcm_priority_spec.rb +40 -0
  49. data/spec/functional/webpush_spec.rb +30 -0
  50. data/spec/spec_helper.rb +2 -0
  51. data/spec/support/simplecov_helper.rb +1 -1
  52. data/spec/unit/client/active_record/adm/app_spec.rb +2 -54
  53. data/spec/unit/client/active_record/adm/notification_spec.rb +2 -39
  54. data/spec/unit/client/active_record/apns/app_spec.rb +3 -26
  55. data/spec/unit/client/active_record/apns/feedback_spec.rb +1 -5
  56. data/spec/unit/client/active_record/apns/notification_spec.rb +29 -293
  57. data/spec/unit/client/active_record/apns2/app_spec.rb +4 -0
  58. data/spec/unit/client/active_record/apns2/notification_spec.rb +65 -0
  59. data/spec/unit/client/active_record/apnsp8/notification_spec.rb +28 -0
  60. data/spec/unit/client/active_record/app_spec.rb +1 -26
  61. data/spec/unit/client/active_record/gcm/app_spec.rb +3 -1
  62. data/spec/unit/client/active_record/gcm/notification_spec.rb +6 -88
  63. data/spec/unit/client/active_record/notification_spec.rb +3 -11
  64. data/spec/unit/client/active_record/pushy/app_spec.rb +2 -13
  65. data/spec/unit/client/active_record/pushy/notification_spec.rb +2 -55
  66. data/spec/unit/client/active_record/shared/app.rb +14 -0
  67. data/spec/unit/{notification_shared.rb → client/active_record/shared/notification.rb} +12 -7
  68. data/spec/unit/client/active_record/webpush/app_spec.rb +6 -0
  69. data/spec/unit/client/active_record/webpush/notification_spec.rb +6 -0
  70. data/spec/unit/client/active_record/wns/badge_notification_spec.rb +1 -11
  71. data/spec/unit/client/active_record/wns/raw_notification_spec.rb +3 -12
  72. data/spec/unit/client/active_record/wpns/app_spec.rb +3 -1
  73. data/spec/unit/client/active_record/wpns/notification_spec.rb +2 -17
  74. data/spec/unit/client/redis/adm/app_spec.rb +5 -0
  75. data/spec/unit/client/redis/adm/notification_spec.rb +5 -0
  76. data/spec/unit/client/redis/apns/app_spec.rb +5 -0
  77. data/spec/unit/client/redis/apns/feedback_spec.rb +5 -0
  78. data/spec/unit/client/redis/apns/notification_spec.rb +50 -0
  79. data/spec/unit/client/redis/apns2/app_spec.rb +4 -0
  80. data/spec/unit/client/redis/apns2/notification_spec.rb +50 -0
  81. data/spec/unit/client/redis/apnsp8/notification_spec.rb +29 -0
  82. data/spec/unit/client/redis/app_spec.rb +5 -0
  83. data/spec/unit/client/redis/gcm/app_spec.rb +5 -0
  84. data/spec/unit/client/redis/gcm/notification_spec.rb +5 -0
  85. data/spec/unit/client/redis/notification_spec.rb +5 -0
  86. data/spec/unit/client/redis/pushy/app_spec.rb +5 -0
  87. data/spec/unit/client/redis/pushy/notification_spec.rb +5 -0
  88. data/spec/unit/client/redis/webpush/app_spec.rb +5 -0
  89. data/spec/unit/client/redis/webpush/notification_spec.rb +5 -0
  90. data/spec/unit/client/redis/wns/badge_notification_spec.rb +5 -0
  91. data/spec/unit/client/redis/wns/raw_notification_spec.rb +22 -0
  92. data/spec/unit/client/redis/wpns/app_spec.rb +5 -0
  93. data/spec/unit/client/redis/wpns/notification_spec.rb +5 -0
  94. data/spec/unit/client/shared/adm/app.rb +51 -0
  95. data/spec/unit/client/shared/adm/notification.rb +39 -0
  96. data/spec/unit/client/shared/apns/app.rb +29 -0
  97. data/spec/unit/client/shared/apns/feedback.rb +9 -0
  98. data/spec/unit/client/shared/apns/notification.rb +262 -0
  99. data/spec/unit/client/shared/app.rb +17 -0
  100. data/spec/unit/client/shared/gcm/app.rb +4 -0
  101. data/spec/unit/client/shared/gcm/notification.rb +77 -0
  102. data/spec/unit/client/shared/notification.rb +10 -0
  103. data/spec/unit/client/shared/pushy/app.rb +17 -0
  104. data/spec/unit/client/shared/pushy/notification.rb +55 -0
  105. data/spec/unit/client/shared/webpush/app.rb +33 -0
  106. data/spec/unit/client/shared/webpush/notification.rb +83 -0
  107. data/spec/unit/client/shared/wns/badge_notification.rb +15 -0
  108. data/spec/unit/client/shared/wns/raw_notification.rb +21 -0
  109. data/spec/unit/client/shared/wpns/app.rb +4 -0
  110. data/spec/unit/client/shared/wpns/notification.rb +18 -0
  111. data/spec/unit/daemon/batch_spec.rb +50 -2
  112. data/spec/unit/daemon/delivery_spec.rb +10 -0
  113. data/spec/unit/daemon/pushy/delivery_spec.rb +5 -3
  114. data/spec/unit/daemon/shared/store.rb +312 -0
  115. data/spec/unit/daemon/store/active_record/reconnectable_spec.rb +7 -7
  116. data/spec/unit/daemon/store/active_record_spec.rb +2 -290
  117. data/spec/unit/daemon/store/redis_spec.rb +2 -291
  118. data/spec/unit/daemon/webpush/delivery_spec.rb +144 -0
  119. data/spec/unit_spec_helper.rb +3 -0
  120. metadata +135 -12
  121. data/lib/rpush/client/active_model/apns/binary_notification_validator.rb +0 -16
@@ -0,0 +1,66 @@
1
+ module Rpush
2
+ module Client
3
+ module ActiveModel
4
+ module Webpush
5
+ module Notification
6
+
7
+ class RegistrationValidator < ::ActiveModel::Validator
8
+ KEYS = %i[ endpoint keys ].freeze
9
+ def validate(record)
10
+ return if record.registration_ids.blank?
11
+ return if record.registration_ids.size > 1
12
+ reg = record.registration_ids.first
13
+ unless reg.is_a?(Hash) &&
14
+ reg.keys.sort == KEYS &&
15
+ reg[:endpoint].is_a?(String) &&
16
+ reg[:keys].is_a?(Hash)
17
+ record.errors.add(:base, 'Registration must have :endpoint (String) and :keys (Hash) keys')
18
+ end
19
+ end
20
+ end
21
+
22
+ def self.included(base)
23
+ base.instance_eval do
24
+ alias_attribute :time_to_live, :expiry
25
+
26
+ validates :registration_ids, presence: true
27
+ validates :data, presence: true
28
+ validates :time_to_live, numericality: { only_integer: true, greater_than: 0 }, allow_nil: true
29
+
30
+ validates_with Rpush::Client::ActiveModel::PayloadDataSizeValidator, limit: 4096
31
+ validates_with Rpush::Client::ActiveModel::RegistrationIdsCountValidator, limit: 1
32
+ validates_with RegistrationValidator
33
+ end
34
+ end
35
+
36
+ def data=(value)
37
+ value = value.stringify_keys if value.respond_to?(:stringify_keys)
38
+ super value
39
+ end
40
+
41
+ def subscription
42
+ @subscription ||= registration_ids.first.deep_symbolize_keys
43
+ end
44
+
45
+ def message
46
+ data['message'].presence if data
47
+ end
48
+
49
+ # https://webpush-wg.github.io/webpush-protocol/#urgency
50
+ def urgency
51
+ data['urgency'].presence if data
52
+ end
53
+
54
+ def as_json(_options = nil)
55
+ {
56
+ 'data' => data,
57
+ 'time_to_live' => time_to_live,
58
+ 'registration_ids' => registration_ids
59
+ }
60
+ end
61
+
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -5,6 +5,7 @@ require 'rpush/client/active_model'
5
5
  require 'rpush/client/active_record/notification'
6
6
  require 'rpush/client/active_record/app'
7
7
 
8
+ require 'rpush/client/active_record/apns/active_record_serializable_notification'
8
9
  require 'rpush/client/active_record/apns/notification'
9
10
  require 'rpush/client/active_record/apns/feedback'
10
11
  require 'rpush/client/active_record/apns/app'
@@ -31,3 +32,6 @@ require 'rpush/client/active_record/adm/app'
31
32
 
32
33
  require 'rpush/client/active_record/pushy/notification'
33
34
  require 'rpush/client/active_record/pushy/app'
35
+
36
+ require 'rpush/client/active_record/webpush/notification'
37
+ require 'rpush/client/active_record/webpush/app'
@@ -0,0 +1,65 @@
1
+ module Rpush
2
+ module Client
3
+ module ActiveRecord
4
+ module Apns
5
+ module ActiveRecordSerializableNotification
6
+ def alert=(alert)
7
+ if alert.is_a?(Hash)
8
+ write_attribute(:alert, multi_json_dump(alert))
9
+ self.alert_is_json = true if has_attribute?(:alert_is_json)
10
+ else
11
+ write_attribute(:alert, alert)
12
+ self.alert_is_json = false if has_attribute?(:alert_is_json)
13
+ end
14
+ end
15
+
16
+ def alert
17
+ string_or_json = read_attribute(:alert)
18
+
19
+ if has_attribute?(:alert_is_json)
20
+ if alert_is_json?
21
+ multi_json_load(string_or_json)
22
+ else
23
+ string_or_json
24
+ end
25
+ else
26
+ begin
27
+ multi_json_load(string_or_json)
28
+ rescue StandardError
29
+ string_or_json
30
+ end
31
+ end
32
+ end
33
+
34
+ def sound=(sound)
35
+ if sound.is_a?(Hash)
36
+ write_attribute(:sound, multi_json_dump(sound))
37
+ self.sound_is_json = true if has_attribute?(:sound_is_json)
38
+ else
39
+ write_attribute(:sound, sound)
40
+ self.sound_is_json = false if has_attribute?(:sound_is_json)
41
+ end
42
+ end
43
+
44
+ def sound
45
+ string_or_json = read_attribute(:sound)
46
+
47
+ if has_attribute?(:sound_is_json)
48
+ if sound_is_json?
49
+ multi_json_load(string_or_json)
50
+ else
51
+ string_or_json
52
+ end
53
+ else
54
+ begin
55
+ multi_json_load(string_or_json)
56
+ rescue StandardError
57
+ string_or_json
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -3,64 +3,8 @@ module Rpush
3
3
  module ActiveRecord
4
4
  module Apns
5
5
  class Notification < Rpush::Client::ActiveRecord::Notification
6
- include Deprecatable
7
6
  include Rpush::Client::ActiveModel::Apns::Notification
8
-
9
- def alert=(alert)
10
- if alert.is_a?(Hash)
11
- write_attribute(:alert, multi_json_dump(alert))
12
- self.alert_is_json = true if has_attribute?(:alert_is_json)
13
- else
14
- write_attribute(:alert, alert)
15
- self.alert_is_json = false if has_attribute?(:alert_is_json)
16
- end
17
- end
18
-
19
- def alert
20
- string_or_json = read_attribute(:alert)
21
-
22
- if has_attribute?(:alert_is_json)
23
- if alert_is_json?
24
- multi_json_load(string_or_json)
25
- else
26
- string_or_json
27
- end
28
- else
29
- begin
30
- multi_json_load(string_or_json)
31
- rescue StandardError
32
- string_or_json
33
- end
34
- end
35
- end
36
-
37
- def sound=(sound)
38
- if sound.is_a?(Hash)
39
- write_attribute(:sound, multi_json_dump(sound))
40
- self.sound_is_json = true if has_attribute?(:sound_is_json)
41
- else
42
- write_attribute(:sound, sound)
43
- self.sound_is_json = false if has_attribute?(:sound_is_json)
44
- end
45
- end
46
-
47
- def sound
48
- string_or_json = read_attribute(:sound)
49
-
50
- if has_attribute?(:sound_is_json)
51
- if sound_is_json?
52
- multi_json_load(string_or_json)
53
- else
54
- string_or_json
55
- end
56
- else
57
- begin
58
- multi_json_load(string_or_json)
59
- rescue StandardError
60
- string_or_json
61
- end
62
- end
63
- end
7
+ include ActiveRecordSerializableNotification
64
8
  end
65
9
  end
66
10
  end
@@ -2,7 +2,10 @@ module Rpush
2
2
  module Client
3
3
  module ActiveRecord
4
4
  module Apns2
5
- class Notification < Rpush::Client::ActiveRecord::Apns::Notification
5
+ class Notification < Rpush::Client::ActiveRecord::Notification
6
+ include Rpush::Client::ActiveModel::Apns::Notification
7
+ include Rpush::Client::ActiveModel::Apns2::Notification
8
+ include Rpush::Client::ActiveRecord::Apns::ActiveRecordSerializableNotification
6
9
  end
7
10
  end
8
11
  end
@@ -3,6 +3,7 @@ module Rpush
3
3
  module ActiveRecord
4
4
  module Apnsp8
5
5
  class Notification < Rpush::Client::ActiveRecord::Apns::Notification
6
+ include Rpush::Client::ActiveModel::Apns2::Notification
6
7
  end
7
8
  end
8
9
  end
@@ -0,0 +1,11 @@
1
+ module Rpush
2
+ module Client
3
+ module ActiveRecord
4
+ module Webpush
5
+ class App < Rpush::Client::ActiveRecord::App
6
+ include Rpush::Client::ActiveModel::Webpush::App
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ module Rpush
2
+ module Client
3
+ module ActiveRecord
4
+ module Webpush
5
+ class Notification < Rpush::Client::ActiveRecord::Notification
6
+ include Rpush::Client::ActiveModel::Webpush::Notification
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
12
+
@@ -44,6 +44,9 @@ require 'rpush/client/redis/wns/badge_notification'
44
44
  require 'rpush/client/redis/pushy/app'
45
45
  require 'rpush/client/redis/pushy/notification'
46
46
 
47
+ require 'rpush/client/redis/webpush/app'
48
+ require 'rpush/client/redis/webpush/notification'
49
+
47
50
  Modis.configure do |config|
48
51
  config.namespace = :rpush
49
52
  end
@@ -3,6 +3,7 @@ module Rpush
3
3
  module Redis
4
4
  module Apns2
5
5
  class Notification < Rpush::Client::Redis::Notification
6
+ include Rpush::Client::ActiveModel::Apns::Notification
6
7
  include Rpush::Client::ActiveModel::Apns2::Notification
7
8
  end
8
9
  end
@@ -3,6 +3,8 @@ module Rpush
3
3
  module Redis
4
4
  module Apnsp8
5
5
  class Notification < Rpush::Client::Redis::Notification
6
+ include Rpush::Client::ActiveModel::Apns::Notification
7
+ include Rpush::Client::ActiveModel::Apns2::Notification
6
8
  include Rpush::Client::ActiveModel::Apnsp8::Notification
7
9
  end
8
10
  end
@@ -9,7 +9,6 @@ module Rpush
9
9
 
10
10
  def time_to_live=(value)
11
11
  self.expiry = value
12
- super
13
12
  end
14
13
  end
15
14
  end
@@ -0,0 +1,15 @@
1
+ module Rpush
2
+ module Client
3
+ module Redis
4
+ module Webpush
5
+ class App < Rpush::Client::Redis::App
6
+ include Rpush::Client::ActiveModel::Webpush::App
7
+
8
+ def vapid_keypair=(value)
9
+ self.certificate = value
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module Rpush
2
+ module Client
3
+ module Redis
4
+ module Webpush
5
+ class Notification < Rpush::Client::Redis::Notification
6
+ include Rpush::Client::ActiveModel::Webpush::Notification
7
+
8
+ def time_to_live=(value)
9
+ self.expiry = value
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -16,7 +16,7 @@ module Rpush
16
16
  end
17
17
  end
18
18
 
19
- CURRENT_ATTRS = [:push_poll, :embedded, :pid_file, :batch_size, :push, :client, :logger, :log_file, :foreground, :log_level, :plugin, :apns]
19
+ CURRENT_ATTRS = [:push_poll, :embedded, :pid_file, :batch_size, :push, :client, :logger, :log_file, :foreground, :foreground_logging, :log_level, :plugin, :apns]
20
20
  DEPRECATED_ATTRS = []
21
21
  CONFIG_ATTRS = CURRENT_ATTRS + DEPRECATED_ATTRS
22
22
 
@@ -53,6 +53,7 @@ module Rpush
53
53
  self.log_level = (defined?(Rails) && Rails.logger) ? Rails.logger.level : ::Logger::Severity::DEBUG
54
54
  self.plugin = OpenStruct.new
55
55
  self.foreground = false
56
+ self.foreground_logging = true
56
57
 
57
58
  self.apns = ApnsConfiguration.new
58
59
 
@@ -105,7 +106,7 @@ module Rpush
105
106
  client_module = Rpush::Client.const_get(client.to_s.camelize)
106
107
  Rpush.send(:include, client_module) unless Rpush.ancestors.include?(client_module)
107
108
 
108
- [:Apns, :Gcm, :Wpns, :Wns, :Adm, :Pushy].each do |service|
109
+ [:Apns, :Gcm, :Wpns, :Wns, :Adm, :Pushy, :Webpush].each do |service|
109
110
  Rpush.const_set(service, client_module.const_get(service)) unless Rpush.const_defined?(service)
110
111
  end
111
112
 
data/lib/rpush/daemon.rb CHANGED
@@ -68,6 +68,9 @@ require 'rpush/daemon/adm'
68
68
  require 'rpush/daemon/pushy'
69
69
  require 'rpush/daemon/pushy/delivery'
70
70
 
71
+ require 'rpush/daemon/webpush/delivery'
72
+ require 'rpush/daemon/webpush'
73
+
71
74
  module Rpush
72
75
  module Daemon
73
76
  class << self
@@ -109,7 +112,7 @@ module Rpush
109
112
  Feeder.stop
110
113
  AppRunner.stop
111
114
  delete_pid_file
112
- puts Rainbow('✔').red if Rpush.config.foreground
115
+ puts Rainbow('✔').red if Rpush.config.foreground && Rpush.config.foreground_logging
113
116
  end
114
117
  end
115
118
 
@@ -37,7 +37,7 @@ module Rpush
37
37
  Rpush::Daemon.store.release_connection
38
38
  end
39
39
 
40
- puts Rainbow('✔').green if Rpush.config.foreground
40
+ puts Rainbow('✔').green if Rpush.config.foreground && Rpush.config.foreground_logging
41
41
  end
42
42
 
43
43
  def stop
@@ -7,6 +7,7 @@ module Rpush
7
7
 
8
8
  class Delivery < Rpush::Daemon::Delivery
9
9
  RETRYABLE_CODES = [ 429, 500, 503 ]
10
+ CLIENT_JOIN_TIMEOUT = 60
10
11
 
11
12
  def initialize(app, http2_client, batch)
12
13
  @app = app
@@ -20,7 +21,11 @@ module Rpush
20
21
  end
21
22
 
22
23
  # Send all preprocessed requests at once
23
- @client.join
24
+ @client.join(timeout: CLIENT_JOIN_TIMEOUT)
25
+ rescue NetHttp2::AsyncRequestTimeout => error
26
+ mark_batch_retryable(Time.now + 10.seconds, error)
27
+ @client.close
28
+ raise
24
29
  rescue Errno::ECONNREFUSED, SocketError => error
25
30
  mark_batch_retryable(Time.now + 10.seconds, error)
26
31
  raise
@@ -102,7 +107,13 @@ module Rpush
102
107
  end
103
108
 
104
109
  def prepare_headers(notification)
105
- notification_data(notification)[HTTP2_HEADERS_KEY] || {}
110
+ headers = {}
111
+
112
+ headers['apns-expiration'] = '0'
113
+ headers['apns-priority'] = '10'
114
+ headers['apns-topic'] = @app.bundle_id
115
+
116
+ headers.merge notification_data(notification)[HTTP2_HEADERS_KEY] || {}
106
117
  end
107
118
 
108
119
  def notification_data(notification)
@@ -7,6 +7,7 @@ module Rpush
7
7
 
8
8
  class Delivery < Rpush::Daemon::Delivery
9
9
  RETRYABLE_CODES = [ 429, 500, 503 ]
10
+ CLIENT_JOIN_TIMEOUT = 60
10
11
 
11
12
  def initialize(app, http2_client, token_provider, batch)
12
13
  @app = app
@@ -22,7 +23,11 @@ module Rpush
22
23
  end
23
24
 
24
25
  # Send all preprocessed requests at once
25
- @client.join
26
+ @client.join(timeout: CLIENT_JOIN_TIMEOUT)
27
+ rescue NetHttp2::AsyncRequestTimeout => error
28
+ mark_batch_retryable(Time.now + 10.seconds, error)
29
+ @client.close
30
+ raise
26
31
  rescue Errno::ECONNREFUSED, SocketError, HTTP2::Error::StreamLimitExceeded => error
27
32
  # TODO restart connection when StreamLimitExceeded
28
33
  mark_batch_retryable(Time.now + 10.seconds, error)
@@ -133,7 +138,7 @@ module Rpush
133
138
  jwt_token = @token_provider.token
134
139
 
135
140
  headers = {}
136
-
141
+
137
142
  headers['content-type'] = 'application/json'
138
143
  headers['apns-expiration'] = '0'
139
144
  headers['apns-priority'] = '10'