class Rpush::Daemon::Gcm::Delivery
Constants
- FCM_URI
- INVALID_REGISTRATION_ID_STATES
- UNAVAILABLE_STATES
Public Class Methods
new(app, http, notification, batch)
click to toggle source
# File lib/rpush/daemon/gcm/delivery.rb, line 13 def initialize(app, http, notification, batch) @app = app @http = http @notification = notification @batch = batch end
Public Instance Methods
perform()
click to toggle source
# File lib/rpush/daemon/gcm/delivery.rb, line 20 def perform handle_response(do_post) rescue SocketError => error mark_retryable(@notification, Time.now + 10.seconds, error) raise rescue StandardError => error mark_failed(error) raise ensure @batch.notification_processed end
Protected Instance Methods
bad_gateway(response)
click to toggle source
# File lib/rpush/daemon/gcm/delivery.rb, line 126 def bad_gateway(response) retry_delivery(@notification, response) log_warn("GCM responded with a Bad Gateway Error. " + retry_message) end
bad_request()
click to toggle source
# File lib/rpush/daemon/gcm/delivery.rb, line 113 def bad_request fail Rpush::DeliveryError.new(400, @notification.id, 'GCM failed to parse the JSON request. Possibly an Rpush bug, please open an issue.') end
create_new_notification(response, unavailable_idxs)
click to toggle source
# File lib/rpush/daemon/gcm/delivery.rb, line 106 def create_new_notification(response, unavailable_idxs) attrs = { 'app_id' => @notification.app_id, 'collapse_key' => @notification.collapse_key, 'delay_while_idle' => @notification.delay_while_idle } registration_ids = @notification.registration_ids.values_at(*unavailable_idxs) Rpush::Daemon.store.create_gcm_notification(attrs, @notification.data, registration_ids, deliver_after_header(response), @app) end
deliver_after_header(response)
click to toggle source
# File lib/rpush/daemon/gcm/delivery.rb, line 141 def deliver_after_header(response) Rpush::Daemon::RetryHeaderParser.parse(response.header['retry-after']) end
do_post()
click to toggle source
# File lib/rpush/daemon/gcm/delivery.rb, line 158 def do_post post = Net::HTTP::Post.new(FCM_URI.path, 'Content-Type' => 'application/json', 'Authorization' => "key=#{@app.auth_key}") post.body = @notification.as_json.to_json @http.request(FCM_URI, post) end
handle_errors(failures)
click to toggle source
# File lib/rpush/daemon/gcm/delivery.rb, line 97 def handle_errors(failures) failures.each do |result| reflect(:gcm_failed_to_recipient, @notification, result[:error], result[:registration_id]) end failures[:invalid].each do |result| reflect(:gcm_invalid_registration_id, @app, result[:error], result[:registration_id]) end end
handle_failures(failures, response)
click to toggle source
# File lib/rpush/daemon/gcm/delivery.rb, line 82 def handle_failures(failures, response) if failures[:unavailable].count == @notification.registration_ids.count retry_delivery(@notification, response) log_warn("All recipients unavailable. #{retry_message}") else if failures[:unavailable].any? unavailable_idxs = failures[:unavailable].map { |result| result[:index] } new_notification = create_new_notification(response, unavailable_idxs) failures.description += " #{unavailable_idxs.join(', ')} will be retried as notification #{new_notification.id}." end handle_errors(failures) fail Rpush::DeliveryError.new(nil, @notification.id, failures.description) end end
handle_response(response)
click to toggle source
# File lib/rpush/daemon/gcm/delivery.rb, line 34 def handle_response(response) case response.code.to_i when 200 ok(response) when 400 bad_request when 401 unauthorized when 500 internal_server_error(response) when 502 bad_gateway(response) when 503 service_unavailable(response) when 500..599 other_5xx_error(response) else fail Rpush::DeliveryError.new(response.code.to_i, @notification.id, Rpush::Daemon::HTTP_STATUS_CODES[response.code.to_i]) end end
handle_successes(successes)
click to toggle source
# File lib/rpush/daemon/gcm/delivery.rb, line 74 def handle_successes(successes) successes.each do |result| reflect(:gcm_delivered_to_recipient, @notification, result[:registration_id]) next unless result.key?(:canonical_id) reflect(:gcm_canonical_id, result[:registration_id], result[:canonical_id]) end end
internal_server_error(response)
click to toggle source
# File lib/rpush/daemon/gcm/delivery.rb, line 121 def internal_server_error(response) retry_delivery(@notification, response) log_warn("GCM responded with an Internal Error. " + retry_message) end
ok(response)
click to toggle source
# File lib/rpush/daemon/gcm/delivery.rb, line 55 def ok(response) results = process_response(response) handle_successes(results.successes) if results.failures.any? handle_failures(results.failures, response) else mark_delivered log_info("#{@notification.id} sent to #{@notification.registration_ids.join(', ')}") end end
other_5xx_error(response)
click to toggle source
# File lib/rpush/daemon/gcm/delivery.rb, line 136 def other_5xx_error(response) retry_delivery(@notification, response) log_warn("GCM responded with a 5xx Error. " + retry_message) end
process_response(response)
click to toggle source
# File lib/rpush/daemon/gcm/delivery.rb, line 67 def process_response(response) body = multi_json_load(response.body) results = Results.new(body['results'], @notification.registration_ids) results.process(invalid: INVALID_REGISTRATION_ID_STATES, unavailable: UNAVAILABLE_STATES) results end
retry_delivery(notification, response)
click to toggle source
# File lib/rpush/daemon/gcm/delivery.rb, line 145 def retry_delivery(notification, response) time = deliver_after_header(response) if time mark_retryable(notification, time) else mark_retryable_exponential(notification) end end
retry_message()
click to toggle source
# File lib/rpush/daemon/gcm/delivery.rb, line 154 def retry_message "Notification #{@notification.id} will be retried after #{@notification.deliver_after.strftime('%Y-%m-%d %H:%M:%S')} (retry #{@notification.retries})." end