Skip to content

Instantly share code, notes, and snippets.

@andyl
Created September 21, 2011 18:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andyl/1232903 to your computer and use it in GitHub Desktop.
Save andyl/1232903 to your computer and use it in GitHub Desktop.
# The mail servers of many SMS gateways treat email as spam if the mails
# arrive too frequently. This has happened using the SMS-gateways managed
# by Verizon and Sprint.
#
# Maintains a queue of delivery addresses for a given carrier.
# Limits the sending frequency, to reduce the chance of being rejected as spam.
#
class CarrierQueue
TIME_DELAY_PER_CARRIER = 5 # seconds
TIME_DELAY_PER_MESSAGE = 0.25 # seconds
def initialize
@address_queue = []
@wait_time = nil
end
def count
@address_queue.count
end
def add(address_object)
@address_queue << address_object
end
def get
sleep TIME_DELAY_PER_MESSAGE
return nil unless get_able?
@wait_time = Time.now + TIME_DELAY_PER_CARRIER
@address_queue.pop
end
def get_able?
return false if @address_queue.empty?
return false unless @wait_time.nil? || Time.now > @wait_time
true
end
end
# Maintains a collection of CarrierQueues. Orders the queues for maximum
# sending efficiency, given the built-in time delay for each carrier.
#
# Simple Test Example using load_all / get_all:
# collection = CarrierQueueCollection.new
# collection.load_all(Phone)
# collection.get_all
#
# Example: sending email messages to selected members
# collection = CarrierQueueCollection.new
# collection.load_all(Phones.where(:member_id => [1,3,4,5]))
# message = "example pager message"
# while phone_object = collection.get
# Mail.send(message, phone_object)
# end
#
class CarrierQueueCollection
def initialize
@queue_hash = {}
end
def add(address_object)
carrier = address_object.email_org
return if carrier.blank?
@queue_hash[carrier] = CarrierQueue.new if @queue_hash[carrier].nil?
@queue_hash[carrier].add(address_object)
end
def load_all(class_name)
class_name.pagable.all.each {|address_object| add(address_object)}
end
def get_all
while address_object = get
puts address_object.email_address
end
end
def get
remove_empty_queues_from_hash
return nil if @queue_hash.empty?
queues = sort_queues_by_count
queue = queues.find {|x| x.get_able?} while queue.nil?
queue.get
end
private
def sort_queues_by_count
@queue_hash.values.sort {|x,y| y.count <=> x.count}
end
def remove_empty_queues_from_hash
@queue_hash.delete_if {|k,v| v.count == 0 }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment