Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

In app hup #59

Closed
wants to merge 7 commits into from

2 participants

@dei79

I added RemoteSignals which allows to push signals to the daemon on database level. That is necessary because I want to trigger an HUP when the end user generates a new app. With this patch it's very easy:

Rapns::RemoteSignal.push(:key => :hup)

dei79 added some commits
@dei79 dei79 added support for mdm notifications e49f477
@dei79 dei79 added mdm property aeb2e56
@dei79 dei79 implemented support for database based certificate and connection dis…
…patching
be019b7
@dei79 dei79 Merge remote-tracking branch 'upstream/master'
Conflicts:
	.gitignore
	lib/generators/rapns_generator.rb
	lib/generators/templates/rapns.yml
	lib/rapns/daemon/certificate.rb
	lib/rapns/daemon/configuration.rb
	lib/rapns/daemon/connection.rb
	lib/rapns/daemon/delivery_handler.rb
	lib/rapns/notification.rb
585d311
@dei79 dei79 fixed merge conflicts fc98c04
@dei79 dei79 Added some log messages when the AppRunner receives a synchronisation…
… request. This makes it much easier to debug the HUP request via logfile.
8713fc8
@dei79 dei79 Added RemoteSignals which allows an application to send different sig…
…nals to the RAPNS daemon, e.g. :hup to trigger an hot update
9b6e0ba
@travisbot

This pull request fails (merged 9b6e0ba into 7dbbecf).

@dei79 dei79 closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jun 7, 2012
  1. @dei79
  2. @dei79

    added mdm property

    dei79 authored
  3. @dei79
Commits on Aug 12, 2012
  1. @dei79

    Merge remote-tracking branch 'upstream/master'

    dei79 authored
    Conflicts:
    	.gitignore
    	lib/generators/rapns_generator.rb
    	lib/generators/templates/rapns.yml
    	lib/rapns/daemon/certificate.rb
    	lib/rapns/daemon/configuration.rb
    	lib/rapns/daemon/connection.rb
    	lib/rapns/daemon/delivery_handler.rb
    	lib/rapns/notification.rb
  2. @dei79

    fixed merge conflicts

    dei79 authored
  3. @dei79

    Added some log messages when the AppRunner receives a synchronisation…

    dei79 authored
    … request. This makes it much easier to debug the HUP request via logfile.
  4. @dei79

    Added RemoteSignals which allows an application to send different sig…

    dei79 authored
    …nals to the RAPNS daemon, e.g. :hup to trigger an hot update
This page is out of date. Refresh to see the latest.
View
3  .gitignore
@@ -5,4 +5,5 @@ pkg/*
coverage/
.rbx/
spec/acceptance/fixtures
-.rbenv-version
+.rbenv-version
+.idea
View
2  lib/generators/rapns_generator.rb
@@ -26,4 +26,4 @@ def add_rapns_migration(template)
migration_template "#{template}.rb", "db/migrate/#{template}.rb"
end
end
-end
+end
View
9 lib/generators/templates/add_certname_to_rapns_notifications.rb
@@ -0,0 +1,9 @@
+class AddCertnameToRapnsNotifications < ActiveRecord::Migration
+ def self.up
+ add_column :rapns_notifications, :cert_common, :string, :default => "default"
+ end
+
+ def self.down
+ remove_column :rapns_notifications, :cert_common
+ end
+end
View
9 lib/generators/templates/add_mdmsupport_to_rapns_notifications.rb
@@ -0,0 +1,9 @@
+class AddMdmsupportToRapnsNotifications < ActiveRecord::Migration
+ def self.up
+ add_column :rapns_notifications, :mdm, :string, :null => true
+ end
+
+ def self.down
+ remove_column :rapns_notifications, :mdm
+ end
+end
View
12 lib/generators/templates/create_rapns_remote_signals.rb
@@ -0,0 +1,12 @@
+class CreateRapnsRemoteSignals < ActiveRecord::Migration
+ def self.up
+ create_table :rapns_signals do |t|
+ t.string :signal, :null => false
+ t.text :payload, :null => true
+ end
+ end
+
+ def self.down
+ drop_table :rapns_signals
+ end
+end
View
12 lib/rapns/daemon/app_runner.rb
@@ -33,11 +33,14 @@ def self.deliver(notification)
end
def self.sync
+ Rapns::Daemon.logger.info("[Sync] Received synchonisation request")
apps = Rapns::App.all
apps.each do |app|
if @all[app.key]
+ Rapns::Daemon.logger.info("[Sync] Resyncing app: #{app.key}")
@all[app.key].sync(app)
else
+ Rapns::Daemon.logger.info("[Sync] Loading app: #{app.key}")
push_host, push_port = HOSTS[app.environment.to_sym][:push]
feedback_host, feedback_port = HOSTS[app.environment.to_sym][:feedback]
feedback_poll = Rapns::Daemon.config.feedback_poll
@@ -48,7 +51,12 @@ def self.sync
end
removed = @all.keys - apps.map(&:key)
- removed.each { |key| @all.delete(key).stop }
+ removed.each { |key|
+ Rapns::Daemon.logger.info("[Sync] Removing app: #{key}")
+ @all.delete(key).stop
+ }
+
+ Rapns::Daemon.logger.info("[Sync] Synchronisation request processed")
end
def self.stop
@@ -115,4 +123,4 @@ def start_handler
end
end
end
-end
+end
View
8 lib/rapns/daemon/connection.rb
@@ -90,6 +90,12 @@ def written
end
def setup_ssl_context
+ if @certificate
+ certificate = @certificate.certificate
+ else
+ certificate = Rapns::Daemon.certificate.certificate
+ end
+
ssl_context = OpenSSL::SSL::SSLContext.new
ssl_context.key = OpenSSL::PKey::RSA.new(@certificate, @password)
ssl_context.cert = OpenSSL::X509::Certificate.new(@certificate)
@@ -108,4 +114,4 @@ def connect_socket
end
end
end
-end
+end
View
79 lib/rapns/daemon/delivery_handler.rb
@@ -26,7 +26,11 @@ def initialize(queue, name, host, port, certificate, password)
end
def start
- @connection.connect
+ # get the default connection
+ defaultConnection = @connections["default"]
+
+ # connect to
+ defaultConnection.connect
@thread = Thread.new do
loop do
@@ -43,7 +47,7 @@ def stop
protected
- def deliver(notification)
+ def deliver(notification, connection)
begin
@connection.write(notification.to_binary)
check_for_error if Rapns::Daemon.config.check_for_errors
@@ -67,17 +71,20 @@ def handle_delivery_error(notification, error)
notification.delivered_at = nil
notification.failed = true
notification.failed_at = Time.now
- notification.error_code = error.code
- notification.error_description = error.description
+ begin
+ notification.error_code = error.code
+ notification.error_description = error.description
+ rescue
+ end
notification.save!(:validate => false)
end
end
- def check_for_error
- if @connection.select(SELECT_TIMEOUT)
+ def check_for_error(connection)
+ if connection.select(SELECT_TIMEOUT)
error = nil
- if tuple = @connection.read(ERROR_TUPLE_BYTES)
+ if tuple = connection.read(ERROR_TUPLE_BYTES)
cmd, code, notification_id = tuple.unpack("ccN")
description = APN_ERRORS[code.to_i] || "Unknown error. Possible rapns bug?"
@@ -88,13 +95,64 @@ def check_for_error
begin
Rapns::Daemon.logger.error("[#{@name}] Error received, reconnecting...")
- @connection.reconnect
+ connection.reconnect
ensure
raise error if error
end
end
end
+ def create_connection(conn_type, notification)
+ # check if we need to get the certificate from the database
+ certificate = nil
+ if !conn_type.eql?("default")
+
+ # get the evaluate callback
+ certCallbackName = Rapns::Daemon.configuration.certificate_callback
+
+ # send a message to them
+ begin
+ certificatePEM = eval("#{certCallbackName}(\"#{conn_type}\")")
+ rescue NoMethodError
+ Rapns::Daemon.logger.error("[#{@name}] Invalid method name for certificate evaluation...")
+ raise
+ rescue Exception => error
+ Rapns::Daemon.logger.error("[#{@name}] The evaluation method returned an error, setting this notification as failed...")
+ handle_delivery_error(notification, error)
+ raise
+ end
+
+
+ Rapns::Daemon.logger.info("[#{@name}] Received valid SSL certificate from the database...") if certificatePEM
+ certificate = Certificate.new(certificatePEM, :data => true)
+ end
+
+ host = Rapns::Daemon.configuration.push.host
+ port = Rapns::Daemon.configuration.push.port
+ connection = Connection.new("#{@name}_#{conn_type}", host, port, :certificate => certificate)
+ @connections[conn_type]=connection
+
+ # emit
+ return connection
+ end
+
+ def reuse_or_open_connection(conn_type, notification)
+ if @connections.has_key?(conn_type)
+ connection = @connections[conn_type]
+ else
+ connection = create_connection(conn_type, notification)
+ connection.connect
+ end
+
+ return connection
+ end
+
+ def close_connections()
+ @connections.eache do |c|
+ c.close
+ end
+ end
+
def handle_next_notification
begin
notification = @queue.pop
@@ -104,7 +162,8 @@ def handle_next_notification
end
begin
- deliver(notification)
+ connection = reuse_or_open_connection(notification.cert_common, notification)
+ deliver(notification, connection)
rescue StandardError => e
Rapns::Daemon.logger.error(e)
ensure
@@ -113,4 +172,4 @@ def handle_next_notification
end
end
end
-end
+end
View
19 lib/rapns/remote_signal.rb
@@ -0,0 +1,19 @@
+module Rapns
+ class Signal < ActiveRecord::Base
+ self.table_name = 'rapns_signals'
+
+ attr_accessible :signal, :payload
+
+ validates :signal, :presence => true
+
+ # returns the next signal
+ def self.pop
+ transaction do
+ signal = Signal.first
+ signal.destroy unless signal.nil?
+ end
+
+ signal || nil
+ end
+ end
+end
Something went wrong with that request. Please try again.