cronic 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ == 0.1.0 2012-11-27
2
+
3
+ * Initial release
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Jens Krämer
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,125 @@
1
+ Cronic
2
+ ======
3
+
4
+ Motivation
5
+ ----------
6
+
7
+ While nothing is wrong with Unix cron, it is not the best choice for
8
+ regular jobs that require to be run in the context of your Rails
9
+ application. Spinning up an instance of the application every 10 minutes
10
+ for a job that needs to run this frequently is just a waste of CPU cycles, let
11
+ alone the increased memory usage in case different jobs are running in
12
+ parallel.
13
+
14
+ Building blocks
15
+ ---------------
16
+
17
+ Cronic itself is only a tiny bit of glue code and a Rails generator.
18
+
19
+ The scheduling itself is done by [Rufus
20
+ Scheduler](https://github.com/jmettraux/rufus-scheduler) . I like this
21
+ particular library because it allows you fine grained control over which
22
+ jobs may be run in parallel and which have to be run in sequence via
23
+ mutexes. It also can avoid overlapping with long running jobs. These are
24
+ things that you have to take care of yourself when using Unix cron.
25
+ The daemonizing part is provided by
26
+ [Dante](https://github.com/bazaarlabs/dante), which is amazingly easy
27
+ to use and 'just works'.
28
+ Optional Airbrake integration is also included.
29
+
30
+
31
+ Usage
32
+ -----
33
+
34
+ Three easy steps:
35
+
36
+ **Add Cronic to your Gemfile and run Bundler**
37
+
38
+ echo "gem 'cronic'" >> Gemfile
39
+ bundle install
40
+
41
+ **Run the Rails generator and create job definitions**
42
+
43
+ rails g cronic
44
+
45
+ This will set up `script/cronic`, which you will use to start / stop the
46
+ daemon. It also creates the `config/cronic.d` directory where you will
47
+ store your job definitions. Have a look at `config/cronic.d/sample.rb`
48
+ to get an idea of how to define your jobs. For more information, be sure
49
+ to visit the Rufus-Scheduler documentation. Every method that is
50
+ available on a Rufus::Scheduler instance can be called in the job
51
+ definition files located in `config/cronic.d`.
52
+
53
+ **Run it**
54
+
55
+ script/cronic -d -l log/cronic.log -P tmp/pids/cronic.pid
56
+
57
+ This will run cronic daemonized, logging to log/cronic.log, with a pid
58
+ file located in tmp/pids. To run in the forground for testing purposes,
59
+ just run the script without any parameters.
60
+
61
+ In order to stop the daemon, run
62
+
63
+ script/cronic -k -P tmp/pids/cronic.pid
64
+
65
+
66
+ Error handling
67
+ --------------
68
+
69
+ Any exception thrown during job execution will be caught and logged to
70
+ STDOUT (which goes into the log file specified on the command line). If
71
+ you have [Airbrake](https://github.com/airbrake/airbrake) set up for
72
+ your application, exceptions will also be reported via
73
+ `Airbrake.notify`.
74
+
75
+
76
+ Capistrano
77
+ ----------
78
+
79
+ In order to stop / start / restart Cronic automatically when deploying
80
+ with capistrano, follow these steps:
81
+
82
+ **Include the Cronic recipes in your Capfile or deploy.rb**
83
+
84
+ require 'cronic/recipes'
85
+
86
+ **Hook Cronic tasks to Capistrano's tasks**
87
+
88
+ after "deploy:stop", "cronic:stop"
89
+ after "deploy:start", "cronic:start"
90
+ after "deploy:restart", "cronic:restart"
91
+
92
+ **Optional: customize task behaviour**
93
+
94
+ set :rails_env, 'production' # this is the default
95
+
96
+ # relative to current_path, defaults to log/cronic.log
97
+ set :cronic_log, 'some/log/file'
98
+
99
+ # relative to current_path, defaults to tmp/pids/cronic.pid
100
+ set :cronic_pid, 'some/pid/file'
101
+
102
+ # custom role to have it run on a special server
103
+ role :cron, 'dedicated.cron.server'
104
+ set :cronic_server_role, :cron
105
+
106
+
107
+ Monitoring
108
+ ----------
109
+
110
+ The [Dante docs](https://github.com/bazaarlabs/dante) have an example
111
+ god script that you can use as a starting point for ensuring your
112
+ cronic daemon stays up and running.
113
+
114
+
115
+ Copyright
116
+ ---------
117
+
118
+ Copyright 2012 Jens Krämer, jk@jkraemer.net
119
+ See [LICENSE](https://github.com/jkraemer/cronic/blob/master/LICENSE)
120
+ for details.
121
+
122
+
123
+
124
+
125
+
@@ -0,0 +1 @@
1
+ require "cronic/scheduler"
@@ -0,0 +1,58 @@
1
+ # Capistrano Recipes for managing the cronic daemon
2
+ #
3
+ # Add these callbacks to have the cronic process restart when the server
4
+ # is restarted:
5
+ #
6
+ # after "deploy:stop", "cronic:stop"
7
+ # after "deploy:start", "cronic:start"
8
+ # after "deploy:restart", "cronic:restart"
9
+ #
10
+ # To only spawn the cronic daemon on a specific server specify the
11
+ # cronic_server_role:
12
+ #
13
+ # set :cronic_server_role, :cron
14
+ #
15
+ # You may change the log and pid file locations by defining :cronic_log and
16
+ # :cronic_pid. The RAILS_ENV defaults to production and may be changed by
17
+ # setting :rails_env.
18
+ #
19
+
20
+ Capistrano::Configuration.instance.load do
21
+ namespace :cronic do
22
+ def rails_env
23
+ "RAILS_ENV=#{fetch(:rails_env, 'production')}"
24
+ end
25
+
26
+ def roles
27
+ fetch(:cronic_server_role, :app)
28
+ end
29
+
30
+ def cronic_log
31
+ fetch :cronic_log, 'log/cronic.log'
32
+ end
33
+
34
+ def cronic_pid
35
+ fetch :cronic_pid, 'tmp/pids/cronic.pid'
36
+ end
37
+
38
+ def cronic_command
39
+ fetch(:cronic_command, "script/cronic")
40
+ end
41
+
42
+ desc "Stop the cronic process"
43
+ task :stop, :roles => lambda { roles } do
44
+ run "cd #{current_path};#{rails_env} #{cronic_command} -k -P #{cronic_pid}"
45
+ end
46
+
47
+ desc "Start the cronic process"
48
+ task :start, :roles => lambda { roles } do
49
+ run "cd #{current_path};#{rails_env} #{cronic_command} -d -l #{cronic_log} -P #{cronic_pid}"
50
+ end
51
+
52
+ desc "Restart the cronic process"
53
+ task :restart, :roles => lambda { roles } do
54
+ stop
55
+ start
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,42 @@
1
+ require 'rufus/scheduler'
2
+
3
+ begin
4
+ require 'airbrake'
5
+ rescue LoadError
6
+ # ignore
7
+ end
8
+
9
+ module Cronic
10
+ class Scheduler
11
+
12
+ def initialize
13
+ @rufus_scheduler = Rufus::Scheduler.start_new
14
+ setup_exception_handler
15
+ end
16
+
17
+ def load_jobs(file)
18
+ @rufus_scheduler.instance_eval IO.read file
19
+ end
20
+
21
+ # blocks until the scheduler exits for some reason
22
+ def join
23
+ @rufus_scheduler.join
24
+ end
25
+
26
+ private
27
+
28
+ def setup_exception_handler
29
+ @rufus_scheduler.class_eval do
30
+ define_method :handle_exception do |job, exception|
31
+ puts "job #{job.job_id} caught exception '#{exception}'"
32
+ if defined?(Airbrake)
33
+ Airbrake.notify exception
34
+ else
35
+ puts exception.backtrace.join("\n")
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,3 @@
1
+ module Cronic
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,14 @@
1
+ class CronicGenerator < Rails::Generators::Base
2
+ source_root File.expand_path("../../../templates", __FILE__)
3
+
4
+ desc "Creates the script/cronic daemon control script and sets up job samples in config/cronic.d"
5
+
6
+ def create_scheduler_script
7
+ copy_file "script/cronic"
8
+ chmod 'script/cronic', 0755
9
+ end
10
+
11
+ def create_jobs_dir
12
+ directory "config/cronic.d"
13
+ end
14
+ end
@@ -0,0 +1 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'cronic', 'recipes'))
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cronic
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jens Krämer
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rufus-scheduler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.0.17
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 2.0.17
30
+ - !ruby/object:Gem::Dependency
31
+ name: dante
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 0.1.5
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 0.1.5
46
+ - !ruby/object:Gem::Dependency
47
+ name: rails
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '3'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '3'
62
+ description: Taking advantage of Rufus Scheduler and Dante to provide a long running
63
+ daemon for cron like jobs to be run in the context of your Rails application, without
64
+ loading the full environment each and every time a job is run.
65
+ email:
66
+ - jk@jkraemer.net
67
+ executables: []
68
+ extensions: []
69
+ extra_rdoc_files: []
70
+ files:
71
+ - lib/cronic/recipes.rb
72
+ - lib/cronic/scheduler.rb
73
+ - lib/cronic/version.rb
74
+ - lib/cronic.rb
75
+ - lib/generators/cronic_generator.rb
76
+ - recipes/cronic.rb
77
+ - LICENSE
78
+ - CHANGELOG.md
79
+ - README.md
80
+ homepage: http://github.com/jkraemer/cronic
81
+ licenses: []
82
+ post_install_message:
83
+ rdoc_options: []
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ! '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ! '>='
96
+ - !ruby/object:Gem::Version
97
+ version: 1.3.6
98
+ requirements: []
99
+ rubyforge_project: cronic
100
+ rubygems_version: 1.8.23
101
+ signing_key:
102
+ specification_version: 3
103
+ summary: Cron like scheduler daemon for Rails applications
104
+ test_files: []