apn_sender 1.0.0 → 1.0.1

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.
@@ -30,7 +30,8 @@ where +token+ is the unique identifier of the iPhone to receive the notification
30
30
  # :alert #=> The alert to send
31
31
  # :badge #=> The badge number to send
32
32
  # :sound #=> The sound file to play on receipt, or true to play the default sound installed with your app
33
- # :custom #=> Hash of application-specific custom data to send along with the notification
33
+
34
+ If any other keys are present they'll be be passed along as custom data to your application.
34
35
 
35
36
  === 2. Sending Queued Messages
36
37
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.0
1
+ 1.0.1
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{apn_sender}
8
- s.version = "1.0.0"
8
+ s.version = "1.0.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Kali Donovan"]
12
- s.date = %q{2010-05-06}
12
+ s.date = %q{2010-05-16}
13
13
  s.description = %q{Resque-based background worker to send Apple Push Notifications over a persistent TCP socket. Includes Resque tweaks to allow persistent sockets between jobs, helper methods for enqueueing APN notifications, and a background daemon to send them.}
14
14
  s.email = %q{kali.donovan@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -34,6 +34,7 @@ Gem::Specification.new do |s|
34
34
  "lib/apn/notification.rb",
35
35
  "lib/apn/notification_job.rb",
36
36
  "lib/apn/queue_manager.rb",
37
+ "lib/apn/queue_name.rb",
37
38
  "lib/apn/sender.rb",
38
39
  "lib/apn/sender_daemon.rb",
39
40
  "lib/apn/tasks.rb",
@@ -45,7 +46,7 @@ Gem::Specification.new do |s|
45
46
  s.homepage = %q{http://github.com/kdonovan/apple_push_notification}
46
47
  s.rdoc_options = ["--charset=UTF-8"]
47
48
  s.require_paths = ["lib"]
48
- s.rubygems_version = %q{1.3.5}
49
+ s.rubygems_version = %q{1.3.6}
49
50
  s.summary = %q{Resque-based background worker to send Apple Push Notifications over a persistent TCP socket.}
50
51
  s.test_files = [
51
52
  "test/helper.rb",
@@ -1,21 +1,21 @@
1
1
  # An example Monit configuration file for running the apn_sender background daemon
2
2
  #
3
- # 1. Replace #{app_name} with the path to your configuration
3
+ # 1. Replace #{app_name} with your application name
4
4
  # 2. Add any arguments between apn_sender the and start/stop command
5
- # 3. Install as a monitrc file
5
+ # 3. Install as a monitrc file (paste to bottom of /etc/monit/monitrc, or save as a .monitrc file and include in the main config)
6
6
 
7
7
  check process redis
8
- with pidfile /tmp/redis.pid
8
+ with pidfile /var/run/redis.pid
9
9
  group apn_sender
10
- start program = "/usr/bin/redis-server /etc/redis.conf"
10
+ start program = "/usr/bin/redis-server /etc/redis/redis.conf"
11
11
  stop program = "/bin/echo SHUTDOWN | nc localhost 6379"
12
12
  if failed host 127.0.0.1 port 6379 then restart
13
13
  if 5 restarts within 5 cycles then timeout
14
14
 
15
15
 
16
16
  check process apn_sender
17
- with pidfile /var/www/apps/#{app_name}/shared/pids/apn_sender.pid
17
+ with pidfile /var/www/#{app_name}/shared/pids/apn_sender.pid
18
18
  group apn_sender
19
- start program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/script/apn_sender --environment=production start"
20
- stop program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/script/apn_sender --environment=production stop"
19
+ start program = "/var/www/#{app_name}/current/script/apn_sender --environment=production --verbose start"
20
+ stop program = "/var/www/{#app_name}/current/script/apn_sender --environment=production --verbose stop"
21
21
  depends_on redis
@@ -4,7 +4,6 @@
4
4
  RAILS_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
5
5
 
6
6
  require 'rubygems'
7
- require 'apn'
8
7
  require 'apn/sender_daemon'
9
8
 
10
9
  APN::SenderDaemon.new(ARGV).daemonize
data/lib/apn.rb CHANGED
@@ -3,18 +3,8 @@ require 'resque/plugins/access_worker_from_job'
3
3
  require 'resque/hooks/before_unregister_worker'
4
4
  require 'json'
5
5
 
6
+ require 'apn/queue_name'
6
7
  require 'apn/queue_manager'
7
-
8
- module APN
9
- # Change this to modify the queue notification jobs are pushed to and pulled from
10
- QUEUE_NAME = :apple_push_notifications
11
-
12
- # Enqueues a notification to be sent in the background via the persistent TCP socket, assuming apn_sender is running (or will be soon)
13
- def self.notify(token, opts = {})
14
- APN::QueueManager.enqueue(APN::NotificationJob, token, opts)
15
- end
16
- end
17
-
18
8
  require 'apn/notification'
19
9
  require 'apn/notification_job'
20
10
  require 'apn/connection/base'
@@ -52,6 +52,12 @@ module APN
52
52
  self.logger.send(level, "#{Time.now}: #{message}")
53
53
  end
54
54
 
55
+ # Log the message first, to ensure it reports what went wrong if in daemon mode. Then die, because something went horribly wrong.
56
+ def log_and_die(msg)
57
+ log(:fatal, msg)
58
+ raise msg
59
+ end
60
+
55
61
  def apn_production?
56
62
  @opts[:environment] && @opts[:environment] != '' && :production == @opts[:environment].to_sym
57
63
  end
@@ -62,19 +68,20 @@ module APN
62
68
  @opts[:cert_path] ||= File.join(File.expand_path(RAILS_ROOT), "config", "certs") if defined?(RAILS_ROOT)
63
69
  @opts[:environment] ||= RAILS_ENV if defined?(RAILS_ENV)
64
70
 
65
- raise "Missing certificate path. Please specify :cert_path when initializing class." unless @opts[:cert_path]
71
+ log_and_die("Missing certificate path. Please specify :cert_path when initializing class.") unless @opts[:cert_path]
72
+
66
73
  cert_name = apn_production? ? "apn_production.pem" : "apn_development.pem"
67
74
  cert_path = File.join(@opts[:cert_path], cert_name)
68
75
 
69
76
  @apn_cert = File.exists?(cert_path) ? File.read(cert_path) : nil
70
- raise "Missing apple push notification certificate in #{cert_path}" unless @apn_cert
77
+ log_and_die("Missing apple push notification certificate in #{cert_path}") unless @apn_cert
71
78
  end
72
79
 
73
80
  # Open socket to Apple's servers
74
81
  def setup_connection
75
- raise "Missing apple push notification certificate" unless @apn_cert
82
+ log_and_die("Missing apple push notification certificate") unless @apn_cert
76
83
  return true if @socket && @socket_tcp
77
- raise "Trying to open half-open connection" if @socket || @socket_tcp
84
+ log_and_die("Trying to open half-open connection") if @socket || @socket_tcp
78
85
 
79
86
  ctx = OpenSSL::SSL::SSLContext.new
80
87
  ctx.cert = OpenSSL::X509::Certificate.new(@apn_cert)
@@ -85,8 +92,7 @@ module APN
85
92
  @socket.sync = true
86
93
  @socket.connect
87
94
  rescue SocketError => error
88
- log(:error, "Error with connection to #{apn_host}: #{error}")
89
- raise "Error with connection to #{apn_host}: #{error}"
95
+ log_and_die("Error with connection to #{apn_host}: #{error}")
90
96
  end
91
97
 
92
98
  # Close open sockets
@@ -3,6 +3,11 @@
3
3
  # example implementation
4
4
 
5
5
  module APN
6
+ # Enqueues a notification to be sent in the background via the persistent TCP socket, assuming apn_sender is running (or will be soon)
7
+ def self.notify(token, opts = {})
8
+ APN::QueueManager.enqueue(APN::NotificationJob, token, opts)
9
+ end
10
+
6
11
  # Extends Resque, allowing us to add all the callbacks to Resque we desire without affecting the expected
7
12
  # functionality in the parent app, if we're included in e.g. a Rails application.
8
13
  class QueueManager
@@ -0,0 +1,4 @@
1
+ module APN
2
+ # Change this to modify the queue from which notification jobs are pushed and pulled
3
+ QUEUE_NAME = :apple_push_notifications
4
+ end
@@ -19,7 +19,7 @@ module APN
19
19
  # Send a raw string over the socket to Apple's servers (presumably already formatted by APN::Notification)
20
20
  def send_to_apple( notification, attempt = 0 )
21
21
  if attempt > TIMES_TO_RETRY_SOCKET_ERROR
22
- raise "Error with connection to #{apn_host} (retried #{TIMES_TO_RETRY_SOCKET_ERROR} times): #{error}"
22
+ log_and_die("Error with connection to #{apn_host} (retried #{TIMES_TO_RETRY_SOCKET_ERROR} times): #{error}")
23
23
  end
24
24
 
25
25
  self.socket.write( notification.to_s )
@@ -73,4 +73,5 @@ worker.work(5)
73
73
  args = ['--environment=production', '--cert-path=/Users/kali/Code/insurrection/certs/']
74
74
  APN::SenderDaemon.new(args).daemonize
75
75
 
76
-
76
+ # To run daemonized version in Rails app
77
+ ./script/apn_sender --environment=production start
@@ -1,18 +1,24 @@
1
- # Modified slightly from delayed_job's delayed/command.rb
1
+ # Based roughly on delayed_job's delayed/command.rb
2
2
  require 'rubygems'
3
3
  require 'daemons'
4
4
  require 'optparse'
5
+ require 'logger'
6
+
7
+ require 'apn/queue_name'
8
+ require 'apn/connection/base'
9
+ require 'apn/sender'
5
10
 
6
11
  module APN
7
12
  # A wrapper designed to daemonize an APN::Sender instance to keep in running in the background.
8
- # Connects worker's output to the Rails logger, if available. Creates a pid file suitable for
13
+ # Connects worker's output to a custom logger, if available. Creates a pid file suitable for
9
14
  # monitoring with {monit}[http://mmonit.com/monit/].
10
15
  #
11
- # Based off delayed_job's great example. To use in a Rails app, <code>script/generate apn_sender</code>.
16
+ # Based off delayed_job's great example, except we can be much lighter by not loading the entire
17
+ # Rails environment. To use in a Rails app, <code>script/generate apn_sender</code>.
12
18
  class SenderDaemon
13
19
 
14
20
  def initialize(args)
15
- @options = {:quiet => true, :worker_count => 1, :environment => :development, :delay => 5}
21
+ @options = {:worker_count => 1, :environment => :development, :delay => 5}
16
22
 
17
23
  optparse = OptionParser.new do |opts|
18
24
  opts.banner = "Usage: #{File.basename($0)} [options] start|stop|restart|run"
@@ -24,16 +30,16 @@ module APN
24
30
  opts.on('-e', '--environment=NAME', 'Specifies the environment to run this apn_sender under ([development]/production).') do |e|
25
31
  @options[:environment] = e
26
32
  end
27
- opts.on('--cert-path=NAME', '--certificate-path=NAME', 'Path to directory containing apn .pem certificates.') do |path|
33
+ opts.on('--cert-path=NAME', 'Path to directory containing apn .pem certificates.') do |path|
28
34
  @options[:cert_path] = path
29
35
  end
30
- opts.on('-n', '--number_of_workers=WORKERS', "Number of unique workers to spawn") do |worker_count|
36
+ opts.on('-n', '--number-of-workers=WORKERS', "Number of unique workers to spawn") do |worker_count|
31
37
  @options[:worker_count] = worker_count.to_i rescue 1
32
38
  end
33
39
  opts.on('-v', '--verbose', "Turn on verbose mode") do
34
40
  @options[:verbose] = true
35
41
  end
36
- opts.on('-V', '--very_verbose', "Turn on very verbose mode") do
42
+ opts.on('-V', '--very-verbose', "Turn on very verbose mode") do
37
43
  @options[:very_verbose] = true
38
44
  end
39
45
  opts.on('-d', '--delay=D', "Delay between rounds of work (seconds)") do |d|
@@ -56,14 +62,7 @@ module APN
56
62
  end
57
63
 
58
64
  def run(worker_name = nil)
59
- Dir.chdir(::RAILS_ROOT)
60
- require File.join(::RAILS_ROOT, 'config', 'environment')
61
-
62
- # Replace the default logger
63
65
  logger = Logger.new(File.join(::RAILS_ROOT, 'log', 'apn_sender.log'))
64
- logger.level = ActiveRecord::Base.logger.level
65
- ActiveRecord::Base.logger = logger
66
- ActiveRecord::Base.clear_active_connections!
67
66
 
68
67
  worker = APN::Sender.new(@options)
69
68
  worker.logger = logger
@@ -71,10 +70,10 @@ module APN
71
70
  worker.very_verbose = @options[:very_verbose]
72
71
  worker.work(@options[:delay])
73
72
  rescue => e
74
- logger.fatal(e) if logger.respond_to?(:fatal)
75
73
  STDERR.puts e.message
74
+ logger.fatal(e) if logger && logger.respond_to?(:fatal)
76
75
  exit 1
77
76
  end
78
77
 
79
78
  end
80
- end
79
+ end
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apn_sender
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 0
8
+ - 1
9
+ version: 1.0.1
5
10
  platform: ruby
6
11
  authors:
7
12
  - Kali Donovan
@@ -9,29 +14,33 @@ autorequire:
9
14
  bindir: bin
10
15
  cert_chain: []
11
16
 
12
- date: 2010-05-06 00:00:00 -07:00
17
+ date: 2010-05-16 00:00:00 -07:00
13
18
  default_executable:
14
19
  dependencies:
15
20
  - !ruby/object:Gem::Dependency
16
21
  name: resque
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
20
24
  requirements:
21
25
  - - ">="
22
26
  - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
23
29
  version: "0"
24
- version:
30
+ type: :runtime
31
+ version_requirements: *id001
25
32
  - !ruby/object:Gem::Dependency
26
33
  name: resque-access_worker_from_job
27
- type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
34
+ prerelease: false
35
+ requirement: &id002 !ruby/object:Gem::Requirement
30
36
  requirements:
31
37
  - - ">="
32
38
  - !ruby/object:Gem::Version
39
+ segments:
40
+ - 0
33
41
  version: "0"
34
- version:
42
+ type: :runtime
43
+ version_requirements: *id002
35
44
  description: Resque-based background worker to send Apple Push Notifications over a persistent TCP socket. Includes Resque tweaks to allow persistent sockets between jobs, helper methods for enqueueing APN notifications, and a background daemon to send them.
36
45
  email: kali.donovan@gmail.com
37
46
  executables: []
@@ -59,6 +68,7 @@ files:
59
68
  - lib/apn/notification.rb
60
69
  - lib/apn/notification_job.rb
61
70
  - lib/apn/queue_manager.rb
71
+ - lib/apn/queue_name.rb
62
72
  - lib/apn/sender.rb
63
73
  - lib/apn/sender_daemon.rb
64
74
  - lib/apn/tasks.rb
@@ -79,18 +89,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
79
89
  requirements:
80
90
  - - ">="
81
91
  - !ruby/object:Gem::Version
92
+ segments:
93
+ - 0
82
94
  version: "0"
83
- version:
84
95
  required_rubygems_version: !ruby/object:Gem::Requirement
85
96
  requirements:
86
97
  - - ">="
87
98
  - !ruby/object:Gem::Version
99
+ segments:
100
+ - 0
88
101
  version: "0"
89
- version:
90
102
  requirements: []
91
103
 
92
104
  rubyforge_project:
93
- rubygems_version: 1.3.5
105
+ rubygems_version: 1.3.6
94
106
  signing_key:
95
107
  specification_version: 3
96
108
  summary: Resque-based background worker to send Apple Push Notifications over a persistent TCP socket.