cronic 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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: []