class Rpush::Daemon::Apns2::Delivery
Constants
- CLIENT_JOIN_TIMEOUT
- RETRYABLE_CODES
Public Class Methods
new(app, http2_client, batch)
click to toggle source
# File lib/rpush/daemon/apns2/delivery.rb, line 12 def initialize(app, http2_client, batch) @app = app @client = http2_client @batch = batch end
Public Instance Methods
perform()
click to toggle source
# File lib/rpush/daemon/apns2/delivery.rb, line 18 def perform @batch.each_notification do |notification| prepare_async_post(notification) end # Send all preprocessed requests at once @client.join(timeout: CLIENT_JOIN_TIMEOUT) rescue NetHttp2::AsyncRequestTimeout => error mark_batch_retryable(Time.now + 10.seconds, error) @client.close raise rescue Errno::ECONNREFUSED, SocketError => error mark_batch_retryable(Time.now + 10.seconds, error) raise rescue StandardError => error mark_batch_failed(error) raise ensure @batch.all_processed end
Protected Instance Methods
build_request(notification)
click to toggle source
# File lib/rpush/daemon/apns2/delivery.rb, line 96 def build_request(notification) { path: "/3/device/#{notification.device_token}", headers: prepare_headers(notification), body: prepare_body(notification) } end
failed_message_to_log(notification, response)
click to toggle source
# File lib/rpush/daemon/apns2/delivery.rb, line 129 def failed_message_to_log(notification, response) log_error("Notification #{notification.id} failed, "\ "#{response[:code]}/#{response[:failure_reason]}") end
handle_response(notification, response)
click to toggle source
# File lib/rpush/daemon/apns2/delivery.rb, line 66 def handle_response(notification, response) code = response[:code] case code when 200 ok(notification) when *RETRYABLE_CODES service_unavailable(notification, response) else reflect(:notification_id_failed, @app, notification.id, code, response[:failure_reason]) @batch.mark_failed(notification, response[:code], response[:failure_reason]) failed_message_to_log(notification, response) end end
notification_data(notification)
click to toggle source
# File lib/rpush/daemon/apns2/delivery.rb, line 119 def notification_data(notification) notification.data || {} end
ok(notification)
click to toggle source
# File lib/rpush/daemon/apns2/delivery.rb, line 83 def ok(notification) log_info("#{notification.id} sent to #{notification.device_token}") @batch.mark_delivered(notification) end
prepare_async_post(notification)
click to toggle source
# File lib/rpush/daemon/apns2/delivery.rb, line 42 def prepare_async_post(notification) response = {} request = build_request(notification) http_request = @client.prepare_request(:post, request[:path], body: request[:body], headers: request[:headers] ) http_request.on(:headers) do |hdrs| response[:code] = hdrs[':status'].to_i end http_request.on(:body_chunk) do |body_chunk| next unless body_chunk.present? response[:failure_reason] = JSON.parse(body_chunk)['reason'] end http_request.on(:close) { handle_response(notification, response) } @client.call_async(http_request) end
prepare_body(notification)
click to toggle source
# File lib/rpush/daemon/apns2/delivery.rb, line 104 def prepare_body(notification) hash = notification.as_json.except(HTTP2_HEADERS_KEY) JSON.dump(hash).force_encoding(Encoding::BINARY) end
prepare_headers(notification)
click to toggle source
# File lib/rpush/daemon/apns2/delivery.rb, line 109 def prepare_headers(notification) headers = {} headers['apns-expiration'] = '0' headers['apns-priority'] = '10' headers['apns-topic'] = @app.bundle_id headers.merge notification_data(notification)[HTTP2_HEADERS_KEY] || {} end
retry_message_to_log(notification)
click to toggle source
# File lib/rpush/daemon/apns2/delivery.rb, line 123 def retry_message_to_log(notification) log_warn("Notification #{notification.id} will be retried after "\ "#{notification.deliver_after.strftime('%Y-%m-%d %H:%M:%S')} "\ "(retry #{notification.retries}).") end