Coder Social home page Coder Social logo

darrenboyd / rooster Goto Github PK

View Code? Open in Web Editor NEW

This project forked from findchris/rooster

1.0 1.0 0.0 112 KB

A Rails plugin providing a daemon for running and controlling scheduled tasks from within your application.

Home Page: http://www.foundchris.com/2009/12/08/rooster-a-smarter-daemon-solution-for-rails-apps/

License: MIT License

rooster's Introduction

Rooster

Rooster is a Rails plugin providing a daemon for running and controlling scheduled tasks from within your application.

It consists of a scheduler daemon running an EventMachine loop that maintains a rufus-scheduler to keep track of your tasks. An EventMachine-based TCP server listens for control commands to start and stop your tasks.

The idea is to be able to deploy your Rails app with all of the needed functionality for running tasks in the background. A few example of such tasks:

  • Generating nightly reports.
  • Expiring database records.
  • Pulling an RSS feed every hour.

You can accomplish these same tasks using a combination of cron and script/runner or rake tasks, but I never liked that approach.

The Daemons gem combined with the daemon_generator plugin works well, but we didn't like managing an army of daemon processes. Rooster leverage one daemon for the main EventMachine loop, and dynamically schedules/unschedules tasks via the rufus-scheduler.

This has been tested on Rails 2.2, with preliminary Rails 3.0 support

Setup

Install the plugin

script/plugin install git://github.com/findchris/rooster.git

Install required gems

gem sources -a http://gems.github.com # if you haven't already...

sudo gem install daemons rufus-scheduler eventmachine

If you want to be able to use english time descriptions in your scheduled tasks, like:

scheduler.every '3h', :first_at => Chronic.parse('midnight')

then install Chronic:

sudo gem install chronic

If you are using Rails 3, add these lines to your Gemfile file

# For Rooster
gem 'daemons', '1.1.0'
gem 'eventmachine', '0.12.10'
gem 'rufus-scheduler'
gem 'chronic', '0.2.3', :require=> 'chronic' # if using Chronic...

Usage

generate a new scheduled task:

script/generate rooster_task MyTaskName

fire up the daemon in console mode to test it out

ruby lib/rooster/rooster_daemon.rb run

When you're done, get your system admin (or switch hats) to add the daemon to the system start-up, and capistrano deploy scripts, etc. Something like:

ruby /path/to/rails_app/lib/rooster/rooster_daemon.rb start
  OR
rake rooster:launch

Control Server

You can send commands to the control server using various rake tasks. For a list of rake tasks, run:

rake -T rooster

As an alternative, you can connect to the control server like so:

telnet 127.0.0.1 8080

Valid commands are:

  • list (lists a summary of tasks including task names and scheduled status)
  • start task_name (starts the task with a class name of "task_name")
  • stop task_name (stops the task with a class name of "task_name")
  • start_all (starts all of the available tasks)
  • stop_all (stops all of the available tasks)
  • restart task_name (stop/start)
  • kill task_name (kills the specified task if it's currently running and unschedules it)
  • stop_tag tag (stops all tasks with the specified tag)
  • quit (Closes the connection to the control server)
  • exit (kills the EventMachine loop)

Customization

You can configure the EventMachine control server like so (defaults to: {:host => "127.0.0.1", :port => "8080"}):

Rooster::Runner.server_options = {:host => "1.2.3.4", :port => "5678"}

When the EventMachine or rufus-scheduler encounter an exception, the module Proc Rooster::Runner.error_handler is called. By default, the exception is logged, but this can be customized like so:

Rooster::Runner.error_handler = lambda { |e| HoptoadNotifier.notify(e) }

Rooster has extensive logging, and by default will use the Rails logger if available, falling back on logging to STDOUT. This can be customized:

Rooster::Runner.logger = Logger.new(STDOUT) # or Logger.new(File.join(Rails.root, "log", "rooster.log"))

By default, all tasks are scheduled when the daemon starts. The can be customized like so:

Rooster::Runner.auto_schedule = false

Also, you can schedule only a subset of tasks by specifying an array of tags for the auto_schedule_tags attribute. This is handy for running different tasks on different servers, for example. An omitted or nil value for the auto_schedule_tags attribute will auto-schedule all tasks available if the auto_schedule flag is set. Example:

Rooster::Runner.auto_schedule      = true
Rooster::Runner.auto_schedule_tags = ['app1', 'other_tag']

Finally, there is some (limited) support for command-line parameters to the rooster daemon. This is especially useful for when run rake commands are cumbersome, such as in a monit "start" command. Currently, you may pass in an "auto_schedule_tags" parameter to the daemon, after including a separator of "--", as in:

ruby lib/rooster/rooster_daemon.rb start -- auto_schedule_tags=app1,other_tag

Deployment

A simple capistrano task for restarting the Rooster daemon can be added to your deploy.rb file:

namespace :rooster do
  desc "Reload Rooster Daemon"
  task :reload, :roles => :rooster do
    rails_env = fetch(:rails_env, "production")
    run "cd #{current_path} && sudo rake RAILS_ENV=#{rails_env} rooster:reload"
  end
end

Notes

Because of the way that forked processes work with the Rails environment, you should ensure that all of your database connections are released after usage, as in:

	ActiveRecord::Base.connection_pool.release_connection

Generated Rooster tasks have this included by default with an ensure block.

Author

Chris Johnson

Contributors

Credits

This project was started by Steven Soroka with his scheduler_daemon plugin. I needed the ability to start/stop individual tasks, and so added an EventMachine-based TCP server to listen for control commands. My initial fork of scheduler_daemon became quite different from the original project, and so I decided to just create a new project altogether. My thanks to Steven for kicking this off in the right direction; the result of a few tweets back and forth.

The dependencies of this plugin are all great projects providing great value to the community: EventMachine, rufus-scheduler, Daemons, and Chronic.

rooster's People

Contributors

findchris avatar sleeper avatar edave avatar

Stargazers

Darren Boyd avatar

Watchers

Darren Boyd avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.