rerun_task 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.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in rerun_task.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,32 @@
1
+ Rerun Task
2
+ ==========
3
+
4
+
5
+ Rerun task is gem for checking if your rake task was executed successfully. You have to place all your rake code to `WatchProcess.new("task_name").call{}`. I write below some examples.
6
+
7
+ Examples
8
+ ====
9
+ task :dummy_task => :environment do
10
+ WatchProcess.new("task_name").call do
11
+ # your code write here
12
+ end
13
+ end
14
+
15
+ Now if you run rake task, then is created pid-files of your process. To your crontab place task, which every 5th minute check if all task done successfully.
16
+
17
+ non-rails app
18
+ ====
19
+ If you use as non-rails app, you have to copy /bin/rerun_task_crontab.rb from gem to your app
20
+
21
+ */5 * * * * ruby /path/to/the/your-app/bin/rerun_task_crontab.rb
22
+
23
+ rails app
24
+ ====
25
+
26
+ If you use it in rails app, you can use rails runner
27
+
28
+ */5 * * * * cd path/to/your-app; bundle exec rails runner RerunTask::UnfinishedRunner.crontab_retry
29
+
30
+ Notes
31
+ ====
32
+ In this version is not allowed to run same process in same time.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,3 @@
1
+ load "#{File.dirname(__FILE__)}/../lib/rerun_task.rb"
2
+
3
+ RerunTask::UnfinishedRunner.crontab_retry
@@ -0,0 +1 @@
1
+ pid_dir: "/tmp"
@@ -0,0 +1,4 @@
1
+ require 'yaml'
2
+ module RerunTask
3
+ CONFIG = YAML.load_file("#{File.dirname(__FILE__)}/../../config/rerun_task.yml")
4
+ end
@@ -0,0 +1,16 @@
1
+ module RerunTask
2
+ class Crontab
3
+ attr_accessor :content
4
+ def initialize
5
+ @content = %x[crontab -l]
6
+ @content = @content.split("\n")
7
+ end
8
+
9
+ def find_task(task_name)
10
+ match = @content.reject{|i| !i.include?(task_name)}
11
+ return nil if match.size == 0
12
+ match.first.split(" ")[5,9].join(" ")
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,22 @@
1
+ module RerunTask
2
+ class Pids
3
+ def self.unfinished
4
+ res = []
5
+ Dir.glob("#{RerunTask::CONFIG['pid_dir']}/rerun_task/pids/*.pid").each do |file_path|
6
+ args = {}
7
+ File.open(file_path, 'r') do |f|
8
+ args = ProcessFile.parse_file(f.read)
9
+ end
10
+ next if args[:process_name].nil? || args[:pid].nil?
11
+ p = ProcessFile.load_file("#{RerunTask::CONFIG['pid_dir']}/rerun_task/pids", args[:process_name])
12
+ begin
13
+ p.process_exists?
14
+ rescue
15
+ res << p
16
+ next
17
+ end
18
+ end
19
+ res
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,79 @@
1
+ require 'pathname'
2
+
3
+ module RerunTask
4
+ class ProcessFile
5
+ attr_accessor :process_name, :pid
6
+
7
+ def initialize(pid_dir)
8
+ @pid_dir = pid_dir
9
+ FileUtils.mkdir_p(@pid_dir) unless Dir.exists?(@pid_dir)
10
+ end
11
+
12
+ def create_pid_file
13
+ if File.exists?(path)
14
+ puts "file exists #{path}"
15
+
16
+ process_from_file = ProcessFile.load_file(@pid_dir, process_name)
17
+ raise RuntimeError.new("Process #{process_name} is already running with pid #{process_from_file.pid}") if process_from_file.process_exists?
18
+ end
19
+
20
+ File.open(path, 'w+') do |f|
21
+ f.write(self.to_s)
22
+ end
23
+ end
24
+
25
+ def path
26
+ ProcessFile.create_file_path(@pid_dir, process_name)
27
+ end
28
+
29
+ def self.create_file_path(pid_dir, process_name)
30
+ basename = Pathname.new("#{pid_dir}/#{process_name}.pid").basename
31
+ "#{pid_dir}/#{basename}"
32
+ end
33
+
34
+ def process_name
35
+ @process_name = @process_name || extract_process_name(Process.pid)
36
+ end
37
+
38
+ def to_s
39
+ "#{Process.pid}\n#{process_name}"
40
+ end
41
+
42
+ def process_exists?
43
+ extract_process_name(pid) == @process_name
44
+ end
45
+
46
+ def self.load_file(pid_dir, process_name)
47
+ f = File.open(create_file_path(pid_dir, process_name), 'r')
48
+ p = ProcessFile.new(pid_dir)
49
+ args = parse_file(f.read)
50
+ p.process_name = process_name.nil? ? args[:process_name] : process_name
51
+ p.pid = args[:pid]
52
+ f.close
53
+ p
54
+ end
55
+
56
+ def self.parse_file(string)
57
+ a = string.split("\n")
58
+ { pid: a.first, process_name: a.last }
59
+ end
60
+
61
+ def destroy
62
+ FileUtils.rm(path)
63
+ end
64
+
65
+ private
66
+
67
+ def extract_process_name(pid)
68
+ ps_res = %x[ps ax]
69
+ ps_res = ps_res.split("\n")
70
+ name = ""
71
+ ps_res.each do |line|
72
+ rows = line.split(" ")
73
+ name = rows.last if rows.first == pid.to_s
74
+ end
75
+ raise RuntimeError.new("process_name not found for pid #{pid}") if name === ""
76
+ name
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,14 @@
1
+ module RerunTask
2
+ class UnfinishedRunner
3
+
4
+ def self.crontab_retry
5
+ crontab = Crontab.new()
6
+ Pids.unfinished.each do |process_file|
7
+ cmd = crontab.find_task(process_file.process_name)
8
+ next if cmd.nil?
9
+ puts "Running command #{cmd} again"
10
+ system("#{cmd} &")
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ module RerunTask
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,25 @@
1
+ module RerunTask
2
+ class WatchProcess
3
+
4
+ def initialize(rake_task_name)
5
+ @name = rake_task_name
6
+ @pid_dir = "#{RerunTask::CONFIG['pid_dir']}/rerun_task/pids"
7
+ @process_file = ProcessFile.new(@pid_dir)
8
+ end
9
+
10
+ def call(&block)
11
+ start
12
+ block.call
13
+ finished
14
+ end
15
+
16
+ def start
17
+ @process_file.create_pid_file
18
+ end
19
+
20
+ def finished
21
+ @process_file.destroy
22
+ end
23
+
24
+ end
25
+ end
data/lib/rerun_task.rb ADDED
@@ -0,0 +1,11 @@
1
+ require "rerun_task/version"
2
+ require "rerun_task/config"
3
+ require "rerun_task/watch_process"
4
+ require "rerun_task/process_file"
5
+ require "rerun_task/pids"
6
+ require "rerun_task/crontab"
7
+ require "rerun_task/unfinished_runner"
8
+
9
+ module RerunTask
10
+
11
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "rerun_task/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "rerun_task"
7
+ s.version = RerunTask::VERSION
8
+ s.authors = ["lukasvotypka"]
9
+ s.email = ["lukas.votypka@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Re-run task if is not finished}
12
+ s.description = %q{This gem is developed for handling rake task and re-run them if didn't finished successfully}
13
+
14
+ s.rubyforge_project = "rerun_task"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_development_dependency "test-unit"
22
+ s.add_development_dependency "mocha"
23
+ end
@@ -0,0 +1,70 @@
1
+ require 'test/unit'
2
+ require "mocha/setup"
3
+ require 'rerun_task'
4
+
5
+ class WatchProcessTest < Test::Unit::TestCase
6
+
7
+ # Called before every test method runs. Can be used
8
+ # to set up fixture information.
9
+ def setup
10
+ @process_file = RerunTask::ProcessFile.new("#{RerunTask::CONFIG['pid_dir']}/rerun_task/pids")
11
+ begin
12
+ FileUtils.rm(@process_file.path)
13
+ rescue
14
+ end
15
+ end
16
+
17
+ # Called after every test method runs. Can be used to tear
18
+ # down fixture information.
19
+
20
+ def teardown
21
+ # Do nothing
22
+ end
23
+
24
+ def test_should_start
25
+ #assert_equal("/tmp/rerun_task/pids/watch_process_test.rb.pid", @process_file.path)
26
+ @w = RerunTask::WatchProcess.new("my_test")
27
+ assert_equal(false, File.exists?(@process_file.path))
28
+ @w.start
29
+ assert_equal(true, File.exists?(@process_file.path))
30
+ @w.finished
31
+ assert_equal(false, File.exists?(@process_file.path))
32
+
33
+ @w = RerunTask::WatchProcess.new("my_test")
34
+ @w.start
35
+ @w2 = RerunTask::WatchProcess.new("my_test")
36
+ assert_raise_kind_of(RuntimeError) do
37
+ @w2.start
38
+ end
39
+ @w.finished
40
+ end
41
+
42
+ def test_list_pids
43
+ path = "#{RerunTask::CONFIG['pid_dir']}/rerun_task/pids"
44
+ filename = "#{path}/test_example_task.rb.pid"
45
+ FileUtils.rm(filename) if File.exists?(filename)
46
+ File.open(filename, 'w') do |f|
47
+ f.write("1234\ntest_example_task.rb")
48
+ end
49
+
50
+ unfinished = RerunTask::Pids.unfinished
51
+ assert_equal(1, unfinished.size)
52
+ assert_equal('test_example_task.rb', unfinished.first.process_name)
53
+ end
54
+
55
+ def test_run_from_crontab
56
+ path = "#{RerunTask::CONFIG['pid_dir']}/rerun_task/pids"
57
+ filename = "#{path}/test_example_task.rb.pid"
58
+ FileUtils.rm(filename) if File.exists?(filename)
59
+ File.open(filename, 'w') do |f|
60
+ f.write("1234\ntest_example_task.rb")
61
+ end
62
+
63
+ crontab = RerunTask::Crontab.new()
64
+ crontab.content = ["0 0 1,5,9,13,17,21,25,29 * * ruby test_example_task.rb"]
65
+ res = crontab.find_task('test_example_task.rb')
66
+ assert_equal("ruby test_example_task.rb", res)
67
+
68
+ RerunTask::UnfinishedRunner.crontab_retry()
69
+ end
70
+ end
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rerun_task
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - lukasvotypka
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2013-12-23 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: test-unit
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ type: :development
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: mocha
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ type: :development
36
+ version_requirements: *id002
37
+ description: This gem is developed for handling rake task and re-run them if didn't finished successfully
38
+ email:
39
+ - lukas.votypka@gmail.com
40
+ executables:
41
+ - rerun_task_crontab.rb
42
+ extensions: []
43
+
44
+ extra_rdoc_files: []
45
+
46
+ files:
47
+ - .gitignore
48
+ - Gemfile
49
+ - README.md
50
+ - Rakefile
51
+ - bin/rerun_task_crontab.rb
52
+ - config/rerun_task.yml
53
+ - lib/rerun_task.rb
54
+ - lib/rerun_task/config.rb
55
+ - lib/rerun_task/crontab.rb
56
+ - lib/rerun_task/pids.rb
57
+ - lib/rerun_task/process_file.rb
58
+ - lib/rerun_task/unfinished_runner.rb
59
+ - lib/rerun_task/version.rb
60
+ - lib/rerun_task/watch_process.rb
61
+ - rerun_task.gemspec
62
+ - test/watch_process_test.rb
63
+ homepage: ""
64
+ licenses: []
65
+
66
+ post_install_message:
67
+ rdoc_options: []
68
+
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: "0"
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: "0"
83
+ requirements: []
84
+
85
+ rubyforge_project: rerun_task
86
+ rubygems_version: 1.8.24
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: Re-run task if is not finished
90
+ test_files:
91
+ - test/watch_process_test.rb
92
+ has_rdoc: