require 'rubygems' require 'resque' require 'logger' require 'resque/server' require 'resque_aps/helper' require 'resque_aps/version' require 'resque_aps/server' require 'resque_aps/application' require 'resque_aps/notification' require 'resque_aps/feedback' require 'resque_aps/unknown_attribute_error' module Resque module Plugins module Aps def logger=(logger) @logger = logger end def logger unless @logger @logger = Logger.new(STDOUT) @logger.level = Logger::WARN end @logger end def aps_gateway_host=(host) @aps_gateway_host = host end def aps_gateway_host @aps_gateway_host ||= "gateway.sandbox.push.apple.com" end def aps_gateway_port=(port) @aps_gateway_port = port end def aps_gateway_port @aps_gateway_port ||= 2195 end def aps_feedback_host=(host) @aps_feedback_host = host end def aps_feedback_host @aps_feedback_host ||= "feedback.sandbox.push.apple.com" end def aps_feedback_port=(port) @aps_feedback_port = port end def aps_feedback_port @aps_feedback_port ||= 2196 end def aps_queue_size_upper=(size) @aps_queue_size_upper = size end def aps_queue_size_upper @aps_queue_size_upper ||= 1000 end def aps_application_job_limit=(size) @aps_queue_size_upper = size end def aps_application_job_limit @aps_application_job_limit ||= 5 end def aps_applications_queued_count(application_name) redis.get(aps_application_queued_key(application_name)) || 0 end def enqueue_aps_application(application_name, override = false) count_apps = aps_applications_queued_count(application_name) count_not = aps_notification_count_for_application(application_name) if override || count_apps <= 0 || (count_apps < aps_application_job_limit && (count_not > aps_queue_size_upper && count_not % (aps_queue_size_upper / 10) == 0)) enqueue(Resque::Plugins::Aps::Application, application_name) redis.incr(aps_application_queued_key(application_name)) end end def dequeue_aps_application(application_name) redis.decr(aps_application_queued_key(application_name)) if aps_applications_queued_count(application_name) > 0 end def enqueue_aps(application_name, notification) redis.rpush(aps_application_queue_key(application_name), encode(notification.to_hash)) enqueue_aps_application(application_name) true end def dequeue_aps(application_name) h = decode(redis.lpop(aps_application_queue_key(application_name))) return Resque::Plugins::Aps::Notification.new(h) if h nil end # Returns the number of queued notifications for a given application def aps_notification_count_for_application(application_name) redis.llen(aps_application_queue_key(application_name)).to_i end # Returns an array of queued notifications for the given application def aps_notifications_for_application(application_name, start = 0, count = 1) r = redis.lrange(aps_application_queue_key(application_name), start, count) if r r.map { |h| Resque::Plugins::Aps::Notification.new(decode(h)) } else [] end end def create_aps_application(name, cert_file, cert_passwd = nil) redis.set(aps_application_key(name), encode({'name' => name, 'cert_file' => cert_file, 'cert_passwd' => cert_passwd})) redis.sadd(:aps_applications, name) end def aps_application(name) h = decode(redis.get(aps_application_key(name))) return Resque::Plugins::Aps::Application.new(h) if h nil end # Returns an array of applications based on start and count def aps_application_names(start = 0, count = 1) a = redis.smembers(:aps_applications) return a if count == 0 ret = a[start..(start + count)] return [] unless ret ret end # Returns the number of application queues def aps_applications_count redis.smembers(:aps_applications).size end def aps_application_key(application_name) "aps:application:#{application_name}" end def aps_application_queued_key(application_name) "#{aps_application_key(application_name)}:queued" end def aps_application_queue_key(application_name) "#{aps_application_key(application_name)}:queue" end end end end Resque.extend Resque::Plugins::Aps Resque::Server.class_eval do include Resque::Plugins::Aps::Server end