resque-scheduler 0.0.1

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
+ *.gemspec
2
+ pkg
3
+ nbproject
@@ -0,0 +1,45 @@
1
+ resque-scheduler
2
+ ===============
3
+
4
+ Resque-scheduler is basically the union of rufus-scheduler and resque. The goal
5
+ is to provide simple job scheduling with centralized configuration and
6
+ distributed workers.
7
+
8
+ The schedule is a list of Resque worker classes with arguments and a
9
+ schedule frequency (in crontab syntax). The schedule is just a hash, but
10
+ is most likely stored in a YAML:
11
+
12
+ queue_documents_for_indexing:
13
+ cron: "0 0 * * *"
14
+ class: QueueDocuments
15
+ args:
16
+ description: "This job queues all content for indexing in solr
17
+
18
+ clear_leaderboards_contributors:
19
+ cron: "30 6 * * 1"
20
+ class: ClearLeaderboards
21
+ args: contributors
22
+ description: "This job resets the weekly leaderboard for contributions"
23
+
24
+ clear_leaderboards_moderator:
25
+ cron: "30 6 * * 1"
26
+ class: ClearLeaderboards
27
+ args: moderators
28
+ description: "This job resets the weekly leaderboard for moderators"
29
+
30
+ And then set the schedule wherever you configure Resque, like so:
31
+
32
+ require 'resque-scheduler'
33
+ ResqueScheduler.schedule = YAML.load_file(File.join(File.dirname(__FILE__), '../resque_schedule.yml'))
34
+
35
+ The scheduler process is just a rake task which adds things to resque when they fire
36
+ based on the schedule. For obvious reasons, this process never exits.
37
+
38
+ $ rake resque-scheduler
39
+
40
+ You'll need to add this to your rakefile:
41
+
42
+ require 'resque_scheduler/tasks'
43
+ task "resque:setup" => :environment
44
+
45
+
@@ -0,0 +1,53 @@
1
+ load 'tasks/resque_scheduler.rake'
2
+
3
+ $LOAD_PATH.unshift 'lib'
4
+
5
+ task :default => :test
6
+
7
+ desc "Run tests"
8
+ task :test do
9
+ Dir['test/*_test.rb'].each do |f|
10
+ require f
11
+ end
12
+ end
13
+
14
+
15
+ desc "Build a gem"
16
+ task :gem => [ :test, :gemspec, :build ]
17
+
18
+ begin
19
+ begin
20
+ require 'jeweler'
21
+ rescue LoadError
22
+ puts "Jeweler not available. Install it with: "
23
+ puts "gem install jeweler"
24
+ end
25
+
26
+ require 'resque_scheduler/version'
27
+
28
+ Jeweler::Tasks.new do |gemspec|
29
+ gemspec.name = "resque-scheduler"
30
+ gemspec.summary = ""
31
+ gemspec.description = ""
32
+ gemspec.email = "bvandenbos@gmail.com"
33
+ gemspec.homepage = "http://github.com/bvandenbos/resque-scheduler"
34
+ gemspec.authors = ["Ben VandenBos"]
35
+ gemspec.version = ResqueScheduler::Version
36
+
37
+ gemspec.add_dependency "resque"
38
+ gemspec.add_dependency "rufus-scheduler"
39
+ gemspec.add_development_dependency "jeweler"
40
+ gemspec.add_development_dependency "mocha"
41
+ end
42
+ end
43
+
44
+
45
+ desc "Push a new version to Gemcutter"
46
+ task :publish => [ :test, :gemspec, :build ] do
47
+ system "git tag v#{ResqueScheduler::Version}"
48
+ system "git push origin v#{ResqueScheduler::Version}"
49
+ system "git push origin master"
50
+ system "gem push pkg/resque-scheduler-#{ResqueScheduler::Version}.gem"
51
+ system "git clean -fd"
52
+ exec "rake pages"
53
+ end
@@ -0,0 +1,49 @@
1
+ require 'rufus-scheduler'
2
+ require 'rufus/scheduler'
3
+ require 'thwait'
4
+
5
+ module Resque
6
+
7
+ class Scheduler
8
+
9
+ extend Resque::Helpers
10
+
11
+ class << self
12
+
13
+ # Schedule all jobs and sleep (never returns)
14
+ def run(wait = true)
15
+ puts "Schedule empty! Set Resque.schedule" if Resque.schedule.empty?
16
+
17
+ Resque.schedule.each do |name, config|
18
+ puts "Scheduling #{name}..."
19
+ rufus_scheduler.cron config['cron'] do
20
+ puts "#{Time.now} queuing #{name}"
21
+ enqueue_from_config(config)
22
+ end
23
+ end
24
+ # sleep baby, sleep
25
+ ThreadsWait.all_waits(rufus_scheduler.instance_variable_get("@thread")) if wait
26
+ end
27
+
28
+ def enqueue_from_config(config)
29
+ params = config['args'].nil? ? [] : Array(config['args'])
30
+ Resque.enqueue(constantize(config['class']), *params)
31
+ end
32
+
33
+ def rufus_scheduler
34
+ @rufus_scheduler ||= Rufus::Scheduler.start_new
35
+ end
36
+
37
+ # Stops old rufus scheduler and creates a new one. Returns the new
38
+ # rufus scheduler
39
+ def clear_schedule!
40
+ rufus_scheduler.stop
41
+ @rufus_scheduler = nil
42
+ rufus_scheduler
43
+ end
44
+
45
+ end
46
+
47
+ end
48
+
49
+ end
@@ -0,0 +1,36 @@
1
+ require 'rubygems'
2
+ require 'resque'
3
+ require 'resque_scheduler/version'
4
+ require 'resque/scheduler'
5
+
6
+ module ResqueScheduler
7
+
8
+ #
9
+ # Accepts a new schedule configuration of the form:
10
+ #
11
+ # {some_name => {"cron" => "5/* * * *",
12
+ # "class" => DoSomeWork,
13
+ # "args" => "work on this string",
14
+ # "description" => "this thing works it"s butter off"},
15
+ # ...}
16
+ #
17
+ # :name can be anything and is used only to describe the scheduled job
18
+ # :cron can be any cron scheduling string :job can be any resque job class
19
+ # :class must be a resque worker class
20
+ # :args can be any yaml which will be converted to a ruby literal and passed
21
+ # in a params. (optional)
22
+ # :description is just that, a description of the job (optional). If params is
23
+ # an array, each element in the array is passed as a separate param,
24
+ # otherwise params is passed in as the only parameter to perform.
25
+ def schedule=(schedule_hash)
26
+ @schedule = schedule_hash
27
+ end
28
+
29
+ # Returns the schedule hash
30
+ def schedule
31
+ @schedule ||= {}
32
+ end
33
+
34
+ end
35
+
36
+ Resque.extend ResqueScheduler
@@ -0,0 +1,15 @@
1
+ # require 'resque/tasks'
2
+ # will give you the resque tasks
3
+
4
+ namespace :resque do
5
+ task :setup
6
+
7
+ desc "Start Resque Scheduler"
8
+ task :scheduler => :setup do
9
+ require 'resque'
10
+ require 'resque_scheduler'
11
+
12
+ Resque::Scheduler.run
13
+ end
14
+
15
+ end
@@ -0,0 +1,3 @@
1
+ module ResqueScheduler
2
+ Version = '0.0.1'
3
+ end
@@ -0,0 +1,2 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
+ require 'resque_scheduler/tasks'
@@ -0,0 +1,23 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class Resque::SchedulerTest < Test::Unit::TestCase
4
+
5
+ def setup
6
+ Resque::Scheduler.clear_schedule!
7
+ end
8
+
9
+ def test_enqueue_from_config_puts_stuff_in_the_resque_queue
10
+ Resque.stubs(:enqueue).once.returns(true).with(SomeIvarJob, '/tmp')
11
+ Resque::Scheduler.enqueue_from_config('cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp")
12
+ end
13
+
14
+ def test_config_makes_it_into_the_rufus_scheduler
15
+ assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
16
+
17
+ Resque.schedule = {:some_ivar_job => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp"}}
18
+ Resque::Scheduler.run(false)
19
+
20
+ assert_equal(1, Resque::Scheduler.rufus_scheduler.all_jobs.size)
21
+ end
22
+
23
+ end
@@ -0,0 +1,14 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'mocha'
4
+ $LOAD_PATH.unshift File.dirname(File.expand_path(__FILE__)) + '/../lib'
5
+ require 'resque_scheduler'
6
+
7
+ class SomeJob
8
+ def self.perform(repo_id, path)
9
+ end
10
+ end
11
+
12
+ class SomeIvarJob < SomeJob
13
+ @queue = :ivar
14
+ end
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: resque-scheduler
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ben VandenBos
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-12-21 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: resque
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: rufus-scheduler
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: jeweler
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: mocha
47
+ type: :development
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ description: ""
56
+ email: bvandenbos@gmail.com
57
+ executables: []
58
+
59
+ extensions: []
60
+
61
+ extra_rdoc_files:
62
+ - README.markdown
63
+ files:
64
+ - .gitignore
65
+ - README.markdown
66
+ - Rakefile
67
+ - lib/resque/scheduler.rb
68
+ - lib/resque_scheduler.rb
69
+ - lib/resque_scheduler/tasks.rb
70
+ - lib/resque_scheduler/version.rb
71
+ - tasks/resque_scheduler.rake
72
+ - test/scheduler_test.rb
73
+ - test/test_helper.rb
74
+ has_rdoc: true
75
+ homepage: http://github.com/bvandenbos/resque-scheduler
76
+ licenses: []
77
+
78
+ post_install_message:
79
+ rdoc_options:
80
+ - --charset=UTF-8
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: "0"
88
+ version:
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: "0"
94
+ version:
95
+ requirements: []
96
+
97
+ rubyforge_project:
98
+ rubygems_version: 1.3.5
99
+ signing_key:
100
+ specification_version: 3
101
+ summary: ""
102
+ test_files:
103
+ - test/scheduler_test.rb
104
+ - test/test_helper.rb