apn_sender 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.