Skip to content

Commit

Permalink
Adding Rapns::Config class; Adding support for Config to be modified …
Browse files Browse the repository at this point in the history
…from the rails app 'config/initializers/rapns.rb' file; Adding Feedback receiver call a callback when feedback is received.

For issue ileitch#77
  • Loading branch information
Matt Connolly authored and mattconnolly committed Oct 15, 2012
1 parent db18892 commit 3fd15dd
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 8 deletions.
9 changes: 2 additions & 7 deletions bin/rapns
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,7 @@ require 'rapns'

environment = ARGV[0]

config = Struct.new(:foreground, :push_poll, :feedback_poll, :airbrake_notify, :check_for_errors, :pid_file, :batch_size).new
config.foreground = false
config.push_poll = 2
config.feedback_poll = 60
config.airbrake_notify = true
config.check_for_errors = true
config.batch_size = 5000
config = Rapns.configuration

banner = 'Usage: rapns <Rails environment> [options]'
ARGV.options do |opts|
Expand All @@ -35,6 +29,7 @@ end

ENV['RAILS_ENV'] = environment
load 'config/environment.rb'
load 'config/initializers/rapns.rb' if File.exist?('config/initializers/rapns.rb')

require 'rapns/daemon'
require 'rapns/patches'
Expand Down
1 change: 1 addition & 0 deletions lib/rapns.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
require 'rapns/notification'
require 'rapns/feedback'
require 'rapns/app'
require 'rapns/config'
55 changes: 55 additions & 0 deletions lib/rapns/config.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
module Rapns

# A globally accessible instance of Rapns::Config
def self.configuration
@configuration ||= Rapns::Config.new
end

# Call the given block yielding to it the global Rapns::Config instance for setting
# configuration values / callbacks.
#
# Typically this would be used in your Rails application's config/initializers/rapns.rb file
def self.configure
yield configuration if block_given?
end

# A class to hold Rapns configuration settings and callbacks.
class Config < Struct.new(:foreground, :push_poll, :feedback_poll, :airbrake_notify, :check_for_errors, :pid_file, :batch_size)

attr_accessor :feedback_callback

# Initialize the Config with default values
def initialize
super

# defaults:
self.foreground = false
self.push_poll = 2
self.feedback_poll = 60
self.airbrake_notify = true
self.check_for_errors = true
self.batch_size = 5000
end

# Define a block that will be executed with a Rapns::Feedback instance when feedback has been received from the
# push notification servers that a notification has failed to be delivered. Further notifications should not
# be sent to this device token.
#
# Example usage (in config/initializers/rapns.rb):
#
# Rapns.configure do |config|
# config.on_feedback do |feedback|
# device = Device.find_by_device_token feedback.device_token
# if device
# device.active = false
# device.save
# end
# end
# end
#
# Where `Device` is a model specific to your Rails app that has a `device_token` field.
def on_feedback(&block)
self.feedback_callback = block
end
end
end
7 changes: 6 additions & 1 deletion lib/rapns/daemon/feedback_receiver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,12 @@ def create_feedback(failed_at, device_token)
formatted_failed_at = failed_at.strftime("%Y-%m-%d %H:%M:%S UTC")
with_database_reconnect_and_retry do
Rapns::Daemon.logger.info("[FeedbackReceiver:#{@name}] Delivery failed at #{formatted_failed_at} for #{device_token}")
Rapns::Feedback.create!(:failed_at => failed_at, :device_token => device_token, :app => @name)
feedback = Rapns::Feedback.create!(:failed_at => failed_at, :device_token => device_token, :app => @name)
begin
Rapns.configuration.feedback_callback.call(feedback) if Rapns.configuration.feedback_callback
rescue Exception => e
Rapns::Daemon.logger.error(e)
end
end
end
end
Expand Down
26 changes: 26 additions & 0 deletions spec/rapns/daemon/feedback_receiver_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,30 @@ def connection.read(bytes)
receiver.should_receive(:interrupt_sleep)
receiver.stop
end

it 'calls the configuration feedback_callback when feedback is received and the callback is set' do
stub_connection_read_with_tuple
Rapns::configuration.feedback_callback = Proc.new {}
feedback = Object.new
Rapns::Feedback.stub(:create! => feedback)
Rapns::configuration.feedback_callback.should_receive(:call).with(feedback)
receiver.check_for_feedback
end

it 'catches exceptions in the feedback_callback' do
error = StandardError.new('bork!')
stub_connection_read_with_tuple
callback = Proc.new { raise error }
Rapns::configuration.feedback_callback = callback
expect { receiver.check_for_feedback }.not_to raise_error
end

it 'logs an exception from the feedback_callback' do
error = StandardError.new('bork!')
stub_connection_read_with_tuple
callback = Proc.new { raise error }
Rapns::Daemon.logger.should_receive(:error).with(error)
Rapns::configuration.feedback_callback = callback
receiver.check_for_feedback
end
end

0 comments on commit 3fd15dd

Please sign in to comment.