Created
January 7, 2009 03:36
-
-
Save mikewadhera/44161 to your computer and use it in GitHub Desktop.
an example leveraging jruby-rack jms for background queue + cron in rails
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'queueable' | |
class ApplicationTasks | |
include Queueable | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace :cron do | |
desc "Work to run every 10 minutes" | |
task :ten_minutes => :bootstrap do | |
log_interval :ten_minutes do | |
FacebookAppTasks.fire_send_pending_emails | |
... | |
end | |
end | |
desc "Work to run every 30 minutes" | |
task :half_hourly => :bootstrap do | |
log_interval :half_hourly do | |
end | |
end | |
desc "Work to run every 60 minutes" | |
task :hourly => :bootstrap do | |
log_interval :hourly do | |
CampaignFeatureTasks.fire_refresh_rss_caches | |
... | |
end | |
end | |
desc "Work to run every day after 12:01am" | |
task :daily => :bootstrap do | |
log_interval :daily do | |
BusinessTasks.fire_analyze_opportunities | |
... | |
end | |
end | |
desc "Bootstraps cron environment" | |
task :bootstrap => :environment do | |
ApplicationTasks.logger = Logger.new("#{RAILS_ROOT}/log/cron.log") | |
end | |
# Helper method for logging start/end times for a block of work | |
def log_interval(interval) | |
ApplicationTasks.logger.info("**** Performing #{interval.to_s.humanize} work at #{Time.now.strftime("%Y-%m-%d %H:%M:%S")}") | |
duration = Benchmark.realtime { yield } | |
ApplicationTasks.logger.info("**** Finished #{interval.to_s.humanize} work at #{Time.now.strftime("%Y-%m-%d %H:%M:%S")} (took #{format("%.2f", duration)} seconds) \n") | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
*/9 * * * * cd $rails_root && $jruby -S rake RAILS_ENV=production cron:ten_minutes 2>&1 | |
0,30 * * * * cd $rails_root && $jruby -S rake RAILS_ENV=production cron:half_hourly 2>&1 | |
56 * * * * cd $rails_root && $jruby -S rake RAILS_ENV=production cron:hourly 2>&1 | |
15 0 * * * cd $rails_root && $jruby -S rake RAILS_ENV=production cron:daily 2>&1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'benchmark' | |
module Queueable | |
def self.included(target) | |
target.extend(ClassMethods) | |
end | |
def on_exception(exception) | |
logger.error('Task Error: ' + exception.message) | |
exception.backtrace.each { |line| logger.error("\t#{line}") } | |
logger.error("\n") | |
raise(exception) if !self.class.queueable? | |
end | |
def logger | |
self.class.logger | |
end | |
module ClassMethods | |
def queueable? | |
defined?($servlet_context) | |
end | |
def method_missing(m, *args) | |
super unless m.to_s.match /^fire_/ | |
task = { | |
:class => self.name.to_s, | |
:action => m.to_s.sub(/^fire_/, ''), | |
:args => args | |
} | |
fire(task) | |
end | |
def fire(task) | |
if queueable? | |
JRuby::Rack::Queues.send_message('rack', task) | |
else | |
call(task) | |
end | |
end | |
# Called-back by fire directly or via queue manager with deserialized message | |
def call(task) | |
klass = task[:class].constantize | |
proxy = klass.new | |
action = task[:action] | |
args = task[:args] | |
logger.info("Starting task: #{klass.name}##{action} at #{Time.now.strftime("%Y-%m-%d %H:%M:%S")}") | |
logger.info(" Arguments: #{args.empty? ? '(None)' : args.map { |arg| arg.inspect }.join(',')}") | |
begin | |
duration = Benchmark.realtime { proxy.send(action, *args) } | |
logger.info("Completed task: #{klass.name}##{action} at #{Time.now.strftime("%Y-%m-%d %H:%M:%S")} (took #{format("%.2f", duration)} seconds) \n") | |
rescue => exception | |
proxy.on_exception(exception) | |
end | |
end | |
def logger | |
@logger ||= Logger.new("#{RAILS_ROOT}/log/jms.log") | |
end | |
def logger=(logger) | |
@logger = logger | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This initializer contains code we only want to load in a servlet context | |
if defined?($servlet_context) | |
... | |
# Add JRuby-Rack Queues support | |
require 'jruby/rack/queues' | |
JRuby::Rack::Queues.register_listener("rack", ApplicationTasks) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment