task_manager 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.rvmrc +2 -0
- data/Gemfile +7 -0
- data/README +38 -0
- data/Rakefile +2 -0
- data/bin/task_manager.rb +77 -0
- data/bin/task_manager.sh +67 -0
- data/doc/LICENSE +20 -0
- data/lib/task_manager.rb +50 -0
- data/lib/task_manager/version.rb +14 -0
- data/test/task_manager_test.rb +46 -0
- metadata +107 -0
data/.rvmrc
ADDED
data/Gemfile
ADDED
data/README
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
= task_manager
|
2
|
+
|
3
|
+
A simple wrapper around the Rufus::Scheduler to have a more configurable setup.
|
4
|
+
|
5
|
+
== Installation
|
6
|
+
|
7
|
+
gem install task_manager
|
8
|
+
|
9
|
+
== Usage
|
10
|
+
|
11
|
+
== Development
|
12
|
+
|
13
|
+
If you want to develop it further, patch something or are just plain curious:
|
14
|
+
you're welcome. This should get you started:
|
15
|
+
|
16
|
+
$ git clone git://github.com/kronn/task_manager.git
|
17
|
+
$ bundle install
|
18
|
+
$ ruby test/task_manager_test.rb
|
19
|
+
|
20
|
+
Bundler is only used for installing dependencies.
|
21
|
+
|
22
|
+
The usual pattern for github-projects applies:
|
23
|
+
|
24
|
+
* Fork the project.
|
25
|
+
* Add failing tests.
|
26
|
+
* Improve the code.
|
27
|
+
* Send me a pull request.
|
28
|
+
|
29
|
+
I'll take a look at it and try to integrate it. If I cannot apply your changes
|
30
|
+
or don't want to, I'll let you know.
|
31
|
+
|
32
|
+
== Documentation
|
33
|
+
|
34
|
+
see doc/*
|
35
|
+
|
36
|
+
== Copyright
|
37
|
+
|
38
|
+
Copyright (c) 2010-2011 Matthias Viehweger. See doc/LICENSE for details.
|
data/Rakefile
ADDED
data/bin/task_manager.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# vim:ft=ruby:fileencoding=utf8
|
3
|
+
|
4
|
+
# read environment variables or use default values
|
5
|
+
# RAILS_ENV=${RAILS_ENV:-"staging"}
|
6
|
+
# RUBY_BIN=${RUBY_BIN:-"ruby"}
|
7
|
+
# BASEPATH=${BASEPATH:-"/home/application/projects/rails/$RAILS_ENV/current"}
|
8
|
+
rails_env = Rails.env
|
9
|
+
ruby_bin = 'ruby'
|
10
|
+
base_path = Rails.root
|
11
|
+
|
12
|
+
|
13
|
+
# variables that should only be changed if you REALLY know what you're doing
|
14
|
+
# e.g. the log-filename is hardcoded in the scheduling-script
|
15
|
+
# LOG="$BASEPATH/log/$RAILS_ENV.scheduler.log"
|
16
|
+
# SCHEDULER_FILENAME='tasks.rb'
|
17
|
+
# SCHEDULER="$BASEPATH/config/$SCHEDULER_FILENAME"
|
18
|
+
log = base_path.join('log').join("#{rails_env}.scheduler.log")
|
19
|
+
scheduler_fn = 'tasks.rb'
|
20
|
+
scheduler = basepath.join('config').join(scheduler_fn)
|
21
|
+
|
22
|
+
# PID=`ps aux | grep -v 'grep' | egrep "$RAILS_ENV.*$SCHEDULER_FILENAME" | head -n1 | sed 's/^!gw*\W\+\(\w\+\).*$/\1/'`
|
23
|
+
pid = `ps aux | grep -v 'grep' | egrep "$RAILS_ENV.*$SCHEDULER_FILENAME" | head -n1 | sed 's/^\w*\W\+\(\w\+\).*$/\1/'`
|
24
|
+
|
25
|
+
# # start scheduler in the background
|
26
|
+
# function start_scheduler() {
|
27
|
+
# if [ -z "$PID" ]; then
|
28
|
+
# $RUBY_BIN $SCHEDULER >>$LOG 2>&1 &
|
29
|
+
# disown -a -h
|
30
|
+
# fi
|
31
|
+
# }
|
32
|
+
#
|
33
|
+
# # kill the scheduler if it's running
|
34
|
+
# function kill_scheduler() {
|
35
|
+
# if [ -n "$PID" ]; then
|
36
|
+
# kill $PID
|
37
|
+
# fi;
|
38
|
+
# }
|
39
|
+
#
|
40
|
+
# # actual "init.d"-like interface
|
41
|
+
# case "$1" in
|
42
|
+
# start)
|
43
|
+
# start_scheduler
|
44
|
+
# ;;
|
45
|
+
# stop)
|
46
|
+
# kill_scheduler
|
47
|
+
# ;;
|
48
|
+
# restart)
|
49
|
+
# kill_scheduler
|
50
|
+
# start_scheduler
|
51
|
+
# ;;
|
52
|
+
# status)
|
53
|
+
# if [ -n "$PID" ]; then
|
54
|
+
# echo "Scheduling is active ($PID)"
|
55
|
+
# else
|
56
|
+
# echo "Scheduling is inactive"
|
57
|
+
# fi
|
58
|
+
# ;;
|
59
|
+
# pid)
|
60
|
+
# echo $PID
|
61
|
+
# ;;
|
62
|
+
# *)
|
63
|
+
# echo "Usage: $0 {start|stop|restart|status|pid}"
|
64
|
+
# echo ""
|
65
|
+
# echo "recognized environment variables with default in parentheses:"
|
66
|
+
# echo ""
|
67
|
+
# echo " variables which should be given"
|
68
|
+
# echo " BASEPATH ($BASEPATH)"
|
69
|
+
# echo " RAILS_ENV ($RAILS_ENV)"
|
70
|
+
# echo ""
|
71
|
+
# echo " variables which can be given for optimization reasons"
|
72
|
+
# echo " RUBY_BIN ($RUBY_BIN)"
|
73
|
+
# ;;
|
74
|
+
# esac
|
75
|
+
#
|
76
|
+
# # for the lack of a better return value, exit successfully
|
77
|
+
# exit 0
|
data/bin/task_manager.sh
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
# read environment variables or use default values
|
4
|
+
RAILS_ENV=${RAILS_ENV:-"staging"}
|
5
|
+
RUBY_BIN=${RUBY_BIN:-"ruby"}
|
6
|
+
BASEPATH=${BASEPATH:-"/home/application/projects/rails/$RAILS_ENV/current"}
|
7
|
+
|
8
|
+
# variables that should only be changed if you REALLY know what you're doing
|
9
|
+
# e.g. the log-filename is hardcoded in the scheduling-script
|
10
|
+
LOG="$BASEPATH/log/$RAILS_ENV.scheduler.log"
|
11
|
+
SCHEDULER_FILENAME='tasks.rb'
|
12
|
+
SCHEDULER="$BASEPATH/config/$SCHEDULER_FILENAME"
|
13
|
+
PID=`ps aux | grep -v 'grep' | egrep "$RAILS_ENV.*$SCHEDULER_FILENAME" | head -n1 | sed 's/^\w*\W\+\(\w\+\).*$/\1/'`
|
14
|
+
|
15
|
+
# start scheduler in the background
|
16
|
+
function start_scheduler() {
|
17
|
+
if [ -z "$PID" ]; then
|
18
|
+
$RUBY_BIN $SCHEDULER >>$LOG 2>&1 &
|
19
|
+
disown -a -h
|
20
|
+
fi
|
21
|
+
}
|
22
|
+
|
23
|
+
# kill the scheduler if it's running
|
24
|
+
function kill_scheduler() {
|
25
|
+
if [ -n "$PID" ]; then
|
26
|
+
kill $PID
|
27
|
+
fi;
|
28
|
+
}
|
29
|
+
|
30
|
+
# actual "init.d"-like interface
|
31
|
+
case "$1" in
|
32
|
+
start)
|
33
|
+
start_scheduler
|
34
|
+
;;
|
35
|
+
stop)
|
36
|
+
kill_scheduler
|
37
|
+
;;
|
38
|
+
restart)
|
39
|
+
kill_scheduler
|
40
|
+
start_scheduler
|
41
|
+
;;
|
42
|
+
status)
|
43
|
+
if [ -n "$PID" ]; then
|
44
|
+
echo "Scheduling is active ($PID)"
|
45
|
+
else
|
46
|
+
echo "Scheduling is inactive"
|
47
|
+
fi
|
48
|
+
;;
|
49
|
+
pid)
|
50
|
+
echo $PID
|
51
|
+
;;
|
52
|
+
*)
|
53
|
+
echo "Usage: $0 {start|stop|restart|status|pid}"
|
54
|
+
echo ""
|
55
|
+
echo "recognized environment variables with default in parentheses:"
|
56
|
+
echo ""
|
57
|
+
echo " variables which should be given"
|
58
|
+
echo " BASEPATH ($BASEPATH)"
|
59
|
+
echo " RAILS_ENV ($RAILS_ENV)"
|
60
|
+
echo ""
|
61
|
+
echo " variables which can be given for optimization reasons"
|
62
|
+
echo " RUBY_BIN ($RUBY_BIN)"
|
63
|
+
;;
|
64
|
+
esac
|
65
|
+
|
66
|
+
# for the lack of a better return value, exit successfully
|
67
|
+
exit 0
|
data/doc/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010-2011 Matthias Viehweger
|
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.
|
data/lib/task_manager.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# needs rufus-scheduler
|
2
|
+
require 'rufus/scheduler'
|
3
|
+
require 'pathname'
|
4
|
+
|
5
|
+
class TaskManager
|
6
|
+
attr_accessor :jobs
|
7
|
+
attr_reader :env, :path
|
8
|
+
|
9
|
+
# create the necessary scheduler/job-storages and store a basepath and a environment
|
10
|
+
def initialize(env = 'staging', path = '.')
|
11
|
+
@path = Pathname.new(path)
|
12
|
+
@env = env.to_sym
|
13
|
+
@jobs = {}
|
14
|
+
@schedulers = {}
|
15
|
+
end
|
16
|
+
|
17
|
+
# return a named scheduler
|
18
|
+
def scheduler(key)
|
19
|
+
@schedulers[key] ||= Rufus::Scheduler.start_new
|
20
|
+
end
|
21
|
+
|
22
|
+
# prevent RubyVM from quitting
|
23
|
+
def persist
|
24
|
+
say "Scheduler wird persistiert, alle Definitionen sollten geladen sein."
|
25
|
+
scheduler(:internal).join
|
26
|
+
end
|
27
|
+
|
28
|
+
# unschedule/stop a job
|
29
|
+
def unschedule(key)
|
30
|
+
jobs[key].unschedule
|
31
|
+
jobs[key] = nil
|
32
|
+
say "Job #{key} stopped"
|
33
|
+
end
|
34
|
+
|
35
|
+
# system-call
|
36
|
+
def execute_task(cmd_string)
|
37
|
+
shortened_cmd = cmd_string.gsub(/--trace/, '').strip
|
38
|
+
say "starting #{shortened_cmd}"
|
39
|
+
if system("cd #{path}; RAILS_ENV=#{env} #{cmd_string} >/dev/null 2>>#{path}/log/#{env}.scheduler.log")
|
40
|
+
say "finished #{shortened_cmd}"
|
41
|
+
else
|
42
|
+
say "ERROR in #{shortened_cmd}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# output a message with Time
|
47
|
+
def say(msg)
|
48
|
+
puts "#{Time.now} - #{msg}"
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# vim:ft=ruby:fileencoding=utf-8
|
2
|
+
|
3
|
+
unless defined?(TaskManager::VERSION)
|
4
|
+
module TaskManager
|
5
|
+
VERSION = "0.0.1"
|
6
|
+
DATE = File.mtime(__FILE__)
|
7
|
+
SUMMARY = 'A simple wrapper around the Rufus::Scheduler to have a more configurable setup.'
|
8
|
+
DESCRIPTION = <<-EOT
|
9
|
+
A simple wrapper around the Rufus::Scheduler to have a more configurable setup.
|
10
|
+
|
11
|
+
The Task to be scheduled should be defined in a subclass.
|
12
|
+
EOT
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
require 'more_unit_test/assert_stdout'
|
4
|
+
require 'test/unit'
|
5
|
+
|
6
|
+
require 'task_manager'
|
7
|
+
|
8
|
+
class TaskManagerTest < Test::Unit::TestCase
|
9
|
+
# remember to clean up after each test-run
|
10
|
+
def teardown
|
11
|
+
# @sut.unschedule(:internal)
|
12
|
+
@sut = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
# lets start by trying to create a taskmanager
|
16
|
+
def test_creating_a_blank_taskmanager
|
17
|
+
assert_nothing_raised do
|
18
|
+
TaskManager.new
|
19
|
+
TaskManager.new('staging', '/path/to/project')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# now that thats out of the way, define some helper methods
|
24
|
+
def tm
|
25
|
+
@sut ||= TaskManager.new
|
26
|
+
end
|
27
|
+
|
28
|
+
# assert_stdout_block does Expected==Actual internally, therefore I give a more flexbile expectation
|
29
|
+
class MatchableString < String
|
30
|
+
def initialize(string)
|
31
|
+
@data = string
|
32
|
+
end
|
33
|
+
|
34
|
+
def ==(other)
|
35
|
+
/#{Regexp.escape(@data)}/.match(other)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# on to the show
|
40
|
+
|
41
|
+
def test_taskmanager_can_output_messages
|
42
|
+
assert_stdout_block MatchableString.new('testing') do
|
43
|
+
TaskManager.new.say('testing')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: task_manager
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Mattthias Viehweger
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-04-13 00:00:00 +02:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rufus-scheduler
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 2
|
32
|
+
- 0
|
33
|
+
- 6
|
34
|
+
version: 2.0.6
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: more_unit_test
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 3
|
46
|
+
segments:
|
47
|
+
- 0
|
48
|
+
version: "0"
|
49
|
+
type: :development
|
50
|
+
version_requirements: *id002
|
51
|
+
description: " A simple wrapper around the Rufus::Scheduler to have a more configurable setup.\n\n The Task to be scheduled should be defined in a subclass.\n"
|
52
|
+
email:
|
53
|
+
- kronn@kronn.de
|
54
|
+
executables:
|
55
|
+
- task_manager.rb
|
56
|
+
- task_manager.sh
|
57
|
+
extensions: []
|
58
|
+
|
59
|
+
extra_rdoc_files: []
|
60
|
+
|
61
|
+
files:
|
62
|
+
- .rvmrc
|
63
|
+
- Gemfile
|
64
|
+
- README
|
65
|
+
- Rakefile
|
66
|
+
- bin/task_manager.rb
|
67
|
+
- bin/task_manager.sh
|
68
|
+
- doc/LICENSE
|
69
|
+
- lib/task_manager.rb
|
70
|
+
- lib/task_manager/version.rb
|
71
|
+
- test/task_manager_test.rb
|
72
|
+
has_rdoc: true
|
73
|
+
homepage: http://github.com/kronn/task_manager
|
74
|
+
licenses: []
|
75
|
+
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options: []
|
78
|
+
|
79
|
+
require_paths:
|
80
|
+
- lib
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
hash: 3
|
87
|
+
segments:
|
88
|
+
- 0
|
89
|
+
version: "0"
|
90
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
hash: 3
|
96
|
+
segments:
|
97
|
+
- 0
|
98
|
+
version: "0"
|
99
|
+
requirements: []
|
100
|
+
|
101
|
+
rubyforge_project: task_manager
|
102
|
+
rubygems_version: 1.3.7
|
103
|
+
signing_key:
|
104
|
+
specification_version: 3
|
105
|
+
summary: A simple wrapper around the Rufus::Scheduler to have a more configurable setup.
|
106
|
+
test_files:
|
107
|
+
- test/task_manager_test.rb
|