Permalink
Browse files

Remove rapns.yml in favour of command-line switches.

  • Loading branch information...
1 parent aeaa3c2 commit 972a92d9a03445349c1b2ec23de39eb25f0d0c0f @ileitch committed Jun 18, 2012
View
@@ -61,11 +61,17 @@ The APNs environment is automatically detected from the app certificate, you do
## Starting the rapns Daemon
cd /path/to/rails/app
- bundle exec rapns <Rails environment>
+ bundle exec rapns <Rails environment> [options]
### Options
-* `--foreground` will prevent rapns from forking into a daemon.
+* `-f` `--foreground` Prevent rapns from forking into a daemon.
+* '-P N' '--db-poll N' Frequency in seconds to check for new notifications. Default: 2.
+* '-F N' '--feedback-poll N' Frequency in seconds to check for feedback. Default: 60.
+* '-e' '--no-error-checks' Disables [error checking](#immediately-when-processing-a-notification-for-delivery) after notification delivery. You may want to disable this if you are sending a very high number of notifications.
+* '-n' '--no-airbrake-notify' Disables error notifications via Airbrake.
+* '-p PATH' '--pid-file PATH' Path to write PID file. Relative to Rails root unless absolute.
+* '-b N' '--batch-size N' ActiveRecord batch size of notifications. Increase for possible higher throughput but higher memory footprint. Default: 5000.
## Sending a Notification
@@ -96,28 +102,6 @@ The APNs environment is automatically detected from the app certificate, you do
Please refer to Apple's [documentation](http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ApplePushService/ApplePushService.html#//apple_ref/doc/uid/TP40008194-CH100-SW1) (Tables 3-1 and 3-2).
-## Configuration
-
-Environment configuration lives in `config/rapns/rapns.yml`. For common setups you probably wont need to change this file.
-
-If you want to use rapns in environments other than development or production, you will need to create an entry for it. Simply duplicate the configuration for development or production, depending on which iOS Push Certificate you wish to use.
-
-### Options
-
-* `push` this section contains options to configure the delivery of notifications.
- * `poll` (default: 2) Frequency in seconds to check for new notifications to deliver.
-
-* `feedback` this section contains options to configure feedback checking.
- * `poll` (default: 60) Frequency in seconds to check for new feedback.
-
-* `airbrake_notify` (default: true) Enables/disables error notifications via Airbrake.
-* `pid_file` (default: blank) the file that rapns will write its process ID to. Paths are relative to your project's RAILS_ROOT unless an absolute path is given.
-
-#### Advanced Options
-
-* `check_for_errors` (default: true) Enables/disables [error checking](#immediately-when-processing-a-notification-for-delivery) after notification delivery. You may want to disable this if you are sending a very high number of notifications.
-* `feeder_batch_size` (default: 5000) Sets the ActiveRecord batch size of notifications. Increase for possible higher throughput but higher memory footprint.
-
## Hot App Updates
If you signal the rapns process with `HUP` it will synchronize with the current `Rapns::App` configurations. This includes adding an app, removing and increasing/decreasing the number of connections an app uses.
@@ -153,7 +137,7 @@ It is your responsibility to avoid creating new notifications for devices that n
## Updating rapns
-After updating you should run `rails g rapns` to check for any new migrations or configuration changes.
+After updating you should run `rails g rapns` to check for any new migrations.
## Wiki
View
@@ -3,12 +3,26 @@
require 'optparse'
require 'rapns'
-foreground = false
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
+
banner = 'Usage: rapns <Rails environment> [options]'
ARGV.options do |opts|
opts.banner = banner
- opts.on('-f', '--foreground', 'Run in the foreground.') { foreground = true }
+ opts.on('-f', '--foreground', 'Run in the foreground.') { config.foreground = true }
+ opts.on('-P N', '--db-poll N', Integer, "Frequency in seconds to check for new notifications. Default: #{config.push_poll}.") { |n| config.push_poll = n }
+ opts.on('-F N', '--feedback-poll N', Integer, "Frequency in seconds to check for feedback. Default: #{config.feedback_poll}.") { |n| config.feedback_poll = n }
+ opts.on('-e', '--no-error-checks', 'Disable error checking after notification delivery.') { config.airbrake_notify = false }
+ opts.on('-n', '--no-airbrake-notify', 'Disables error notifications via Airbrake.') { config.check_for_errors = false }
+ opts.on('-p PATH', '--pid-file PATH', String, 'Path to write PID file. Relative to Rails root unless absolute.') { |path| config.pid_file = path }
+ opts.on('-b N', '--batch-size N', Integer, 'ActiveRecord notifications batch size.') { |n| config.batch_size = n }
opts.on('-v', '--version', 'Print this version of rapns.') { puts "rapns #{Rapns::VERSION}"; exit }
opts.on('-h', '--help', 'You\'re looking at it.') { puts opts; exit }
opts.parse!
@@ -25,4 +39,8 @@ load 'config/environment.rb'
require 'rapns/daemon'
require 'rapns/patches'
-Rapns::Daemon.start(environment, foreground)
+if config.pid_file && !Pathname.new(config.pid_file).absolute?
+ config.pid_file = File.join(Rails.root, config.pid_file)
+end
+
+Rapns::Daemon.start(environment, config)
@@ -17,10 +17,6 @@ def copy_migration
add_rapns_migration('create_rapns_apps')
end
- def copy_config
- copy_file 'rapns.yml', 'config/rapns/rapns.yml'
- end
-
protected
def add_rapns_migration(template)
@@ -1,24 +0,0 @@
-development:
- push:
- host: gateway.sandbox.push.apple.com
- port: 2195
- poll: 2
-
- feedback:
- host: feedback.sandbox.push.apple.com
- port: 2196
- poll: 60
-
-production:
- airbrake_notify: true
- pid_file: tmp/pids/rapns.pid
-
- push:
- host: gateway.push.apple.com
- port: 2195
- poll: 2
-
- feedback:
- host: feedback.push.apple.com
- port: 2196
- poll: 60
View
@@ -3,7 +3,6 @@
require 'pathname'
require 'rapns/daemon/interruptible_sleep'
-require 'rapns/daemon/configuration'
require 'rapns/daemon/delivery_error'
require 'rapns/daemon/disconnection_error'
require 'rapns/daemon/connection'
@@ -21,24 +20,23 @@ module Daemon
extend DatabaseReconnectable
class << self
- attr_accessor :logger, :configuration
+ attr_accessor :logger, :config
end
- def self.start(environment, foreground)
+ def self.start(environment, config)
+ self.config = config
+ self.logger = Logger.new(:foreground => config.foreground, :airbrake_notify => config.airbrake_notify)
setup_signal_hooks
- self.configuration = Configuration.load(environment, File.join(Rails.root, 'config', 'rapns', 'rapns.yml'))
- self.logger = Logger.new(:foreground => foreground, :airbrake_notify => configuration.airbrake_notify)
-
- unless foreground
+ unless config.foreground
daemonize
reconnect_database
end
write_pid_file
ensure_upgraded
AppRunner.sync
- Feeder.start(configuration.push.poll)
+ Feeder.start(config.push_poll)
end
protected
@@ -106,17 +104,17 @@ def self.daemonize
end
def self.write_pid_file
- if !configuration.pid_file.blank?
+ if !config.pid_file.blank?
begin
- File.open(configuration.pid_file, 'w') { |f| f.puts Process.pid }
+ File.open(config.pid_file, 'w') { |f| f.puts Process.pid }
rescue SystemCallError => e
- logger.error("Failed to write PID to '#{configuration.pid_file}': #{e.inspect}")
+ logger.error("Failed to write PID to '#{config.pid_file}': #{e.inspect}")
end
end
end
def self.delete_pid_file
- pid_file = configuration.pid_file
+ pid_file = config.pid_file
File.delete(pid_file) if !pid_file.blank? && File.exists?(pid_file)
end
end
@@ -42,8 +42,8 @@ def self.sync
next unless environment
push_host, push_port = HOSTS[environment][:push]
feedback_host, feedback_port = HOSTS[environment][:feedback]
- feedback = Rapns::Daemon.configuration.feedback
- runner = AppRunner.new(app, push_host, push_port, feedback_host, feedback_port, feedback.poll)
+ feedback_poll = Rapns::Daemon.config.feedback_poll
+ runner = AppRunner.new(app, push_host, push_port, feedback_host, feedback_port, feedback_poll)
runner.start
@all[app.key] = runner
end
@@ -1,90 +0,0 @@
-require 'yaml'
-
-module Rapns
- class ConfigurationError < StandardError; end
-
- module Daemon
- class Configuration
- attr_accessor :push, :feedback
- attr_accessor :airbrake_notify, :pid_file, :check_for_errors, :feeder_batch_size
-
- def self.load(environment, config_path)
- configuration = new(environment, config_path)
- configuration.load
- configuration
- end
-
- def initialize(environment, config_path)
- @environment = environment
- @config_path = config_path
-
- self.push = Struct.new(:poll).new
- self.feedback = Struct.new(:poll).new
- end
-
- def load
- config = read_config
- ensure_environment_configured(config)
- config = config[@environment]
-
- load_push(config)
- load_feedback(config)
- load_defaults(config)
- end
-
- def load_push(config)
- set_variable(push, :push, :poll, config, :optional => true, :default => 2)
- end
-
- def load_feedback(config)
- set_variable(feedback, :feedback, :poll, config, :optional => true, :default => 60)
- end
-
- def load_defaults(config)
- set_variable(self, nil, :airbrake_notify, config, :optional => true, :default => true)
- set_variable(self, nil, :pid_file, config, :optional => true, :default => nil, :path => Rails.root)
- set_variable(self, nil, :check_for_errors, config, :optional => true, :default => true)
- set_variable(self, nil, :feeder_batch_size, config, :optional => true, :default => 5000)
- end
-
- protected
-
- def read_config
- ensure_config_exists
- File.open(@config_path) { |fd| YAML.load(fd) }
- end
-
- def set_variable(base, base_key, key, config, options = {})
- if base_key
- value = config.key?(base_key.to_s) ? config[base_key.to_s][key.to_s] : nil
- else
- value = config[key.to_s]
- end
-
- if value.to_s.strip == ""
- if options[:optional]
- base.send("#{key}=", options[:default])
- else
- key_path = base_key ? "#{base_key}.#{key}" : key
- raise Rapns::ConfigurationError, "'#{key_path}' not defined for environment '#{@environment}' in #{@config_path}. You may need to run 'rails g rapns' after updating."
- end
- else
- value = File.join(options[:path], value) if options[:path] && !Pathname.new(value).absolute?
- base.send("#{key}=", value)
- end
- end
-
- def ensure_config_exists
- if !File.exists?(@config_path)
- raise Rapns::ConfigurationError, "#{@config_path} does not exist. Have you run 'rails g rapns'?"
- end
- end
-
- def ensure_environment_configured(config)
- if !config.key?(@environment)
- raise Rapns::ConfigurationError, "Configuration for environment '#{@environment}' not defined in #{@config_path}"
- end
- end
- end
- end
-end
@@ -46,7 +46,7 @@ def stop
def deliver(notification)
begin
@connection.write(notification.to_binary)
- check_for_error if Rapns::Daemon.configuration.check_for_errors
+ check_for_error if Rapns::Daemon.config.check_for_errors
with_database_reconnect_and_retry do
notification.delivered = true
@@ -27,7 +27,7 @@ def self.enqueue_notifications
begin
with_database_reconnect_and_retry do
ready_apps = Rapns::Daemon::AppRunner.ready
- batch_size = Rapns::Daemon.configuration.feeder_batch_size
+ batch_size = Rapns::Daemon.config.batch_size
Rapns::Notification.ready_for_delivery.find_each(:batch_size => batch_size) do |notification|
Rapns::Daemon::AppRunner.deliver(notification) if ready_apps.include?(notification.app)
end
@@ -145,11 +145,10 @@
let(:runner) { stub(:sync => nil, :stop => nil) }
let(:new_runner) { stub }
let(:logger) { stub(:error => nil) }
- let(:feedback_config) { stub(:poll => 60) }
- let(:configuration) { stub(:feedback => feedback_config) }
+ let(:config) { stub(:feedback_poll => 60) }
before do
- Rapns::Daemon.stub(:configuration => configuration, :logger => logger)
+ Rapns::Daemon.stub(:config => config, :logger => logger)
Rapns::Daemon::AppRunner.all['app'] = runner
Rapns::App.stub(:all => [app])
end
@@ -171,7 +170,7 @@
Rapns::App.stub(:all => [new_app])
new_runner = stub
Rapns::Daemon::AppRunner.should_receive(:new).with(new_app, 'gateway.push.apple.com', 2195,
- 'feedback.push.apple.com', 2196, feedback_config.poll).and_return(new_runner)
+ 'feedback.push.apple.com', 2196, config.feedback_poll).and_return(new_runner)
new_runner.should_receive(:start)
Rapns::Daemon::AppRunner.sync
end
@@ -181,7 +180,7 @@
Rapns::App.stub(:all => [new_app])
new_runner = stub
Rapns::Daemon::AppRunner.should_receive(:new).with(new_app, 'gateway.sandbox.push.apple.com', 2195,
- 'feedback.sandbox.push.apple.com', 2196, feedback_config.poll).and_return(new_runner)
+ 'feedback.sandbox.push.apple.com', 2196, config.feedback_poll).and_return(new_runner)
new_runner.should_receive(:start)
Rapns::Daemon::AppRunner.sync
end
Oops, something went wrong.

0 comments on commit 972a92d

Please sign in to comment.