tumugi 0.5.3 → 0.6.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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.travis.yml +3 -0
- data/CHANGELOG.md +44 -2
- data/README.md +5 -91
- data/Rakefile +0 -4
- data/examples/task_inheritance.rb +9 -0
- data/examples/task_parameter.rb +4 -5
- data/lib/tumugi.rb +6 -3
- data/lib/tumugi/cli.rb +31 -6
- data/lib/tumugi/command/new.rb +64 -0
- data/lib/tumugi/command/run.rb +14 -104
- data/lib/tumugi/config.rb +2 -2
- data/lib/tumugi/dag_result_reporter.rb +37 -0
- data/lib/tumugi/data/new/Gemfile.erb +4 -0
- data/lib/tumugi/data/new/README.md.erb +59 -0
- data/lib/tumugi/data/new/Rakefile.erb +10 -0
- data/lib/tumugi/data/new/examples/example.rb.erb +4 -0
- data/lib/tumugi/data/new/gemspec.erb +28 -0
- data/lib/tumugi/data/new/gitignore.erb +6 -0
- data/lib/tumugi/data/new/lib/tumugi/plugin/target/target.rb.erb +20 -0
- data/lib/tumugi/data/new/lib/tumugi/plugin/task/task.rb.erb +22 -0
- data/lib/tumugi/data/new/test/plugin/target/target_test.rb.erb +9 -0
- data/lib/tumugi/data/new/test/plugin/task/task_test.rb.erb +27 -0
- data/lib/tumugi/data/new/test/test.rb.erb +7 -0
- data/lib/tumugi/data/new/test/test_helper.rb.erb +8 -0
- data/lib/tumugi/executor/local_executor.rb +128 -0
- data/lib/tumugi/logger.rb +31 -2
- data/lib/tumugi/mixin/parameterizable.rb +11 -2
- data/lib/tumugi/parameter/parameter.rb +3 -3
- data/lib/tumugi/parameter/parameter_proxy.rb +1 -1
- data/lib/tumugi/task.rb +84 -3
- data/lib/tumugi/task_definition.rb +37 -18
- data/lib/tumugi/test/helper.rb +46 -0
- data/lib/tumugi/version.rb +1 -1
- data/lib/tumugi/{application.rb → workflow.rb} +11 -4
- data/tumugi.gemspec +3 -3
- metadata +39 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8245cbb305b7100cc7b3c522ee232d89ac6704c6
|
4
|
+
data.tar.gz: 3a7b0605e4f5b7e7fbc5b8fa0b77c1c5c9c932c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 081770a32be9360b5c3dec706f5277cfe22c42b1d2ad21771bfa3567b83a75451d7f2ab71dfcf69c5e0391e11b8224172d9ec71a9e7c1b1c40ddf2eaed0c05cf
|
7
|
+
data.tar.gz: 010e6fcb0d19a20c8e7e33fddb06f63cbac19b5f15a45f40cc381cc0c36522fee4ef80b7939358318d2e7b20566ffb65c0f0b4174e2ccb74fdc0aaa0f35dfd38
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,12 +1,54 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
-
## [0.
|
4
|
-
[Full Changelog](https://github.com/tumugi/tumugi/compare/v0.5.
|
3
|
+
## [0.6.0](https://github.com/tumugi/tumugi/tree/0.6.0) (2016-07-09)
|
4
|
+
[Full Changelog](https://github.com/tumugi/tumugi/compare/v0.5.3...0.6.0)
|
5
|
+
|
6
|
+
**Implemented enhancements:**
|
7
|
+
|
8
|
+
- Refactoring executor [\#95](https://github.com/tumugi/tumugi/issues/95)
|
9
|
+
- Improve log [\#87](https://github.com/tumugi/tumugi/issues/87)
|
10
|
+
- DSL improvement [\#81](https://github.com/tumugi/tumugi/issues/81)
|
11
|
+
- Support dryrun option [\#55](https://github.com/tumugi/tumugi/issues/55)
|
12
|
+
- param\_set accept block [\#53](https://github.com/tumugi/tumugi/issues/53)
|
13
|
+
- Plugin test helper [\#29](https://github.com/tumugi/tumugi/issues/29)
|
14
|
+
- Plugin template generator [\#28](https://github.com/tumugi/tumugi/issues/28)
|
15
|
+
- Add Tumugi.app which is alias of Tumugi.application [\#92](https://github.com/tumugi/tumugi/pull/92) ([hakobera](https://github.com/hakobera))
|
16
|
+
- Add short cut method to set parmeter in DSL [\#84](https://github.com/tumugi/tumugi/pull/84) ([hakobera](https://github.com/hakobera))
|
17
|
+
- Improve result table [\#83](https://github.com/tumugi/tumugi/pull/83) ([hakobera](https://github.com/hakobera))
|
18
|
+
- Introduce new DSL syntax: set [\#82](https://github.com/tumugi/tumugi/pull/82) ([hakobera](https://github.com/hakobera))
|
19
|
+
|
20
|
+
**Fixed bugs:**
|
21
|
+
|
22
|
+
- Fix result reporting failed if parameter type is not :string [\#96](https://github.com/tumugi/tumugi/pull/96) ([hakobera](https://github.com/hakobera))
|
23
|
+
- Fix task timeout logic [\#93](https://github.com/tumugi/tumugi/pull/93) ([hakobera](https://github.com/hakobera))
|
24
|
+
|
25
|
+
**Closed issues:**
|
26
|
+
|
27
|
+
- \[Breaking Change\] Remove auto\_bind feature and make accessible CLI param from task [\#88](https://github.com/tumugi/tumugi/issues/88)
|
28
|
+
|
29
|
+
**Merged pull requests:**
|
30
|
+
|
31
|
+
- Remove File.exists? [\#100](https://github.com/tumugi/tumugi/pull/100) ([hakobera](https://github.com/hakobera))
|
32
|
+
- Remove development dependency: github\_changelog\_generator [\#98](https://github.com/tumugi/tumugi/pull/98) ([hakobera](https://github.com/hakobera))
|
33
|
+
- Refactoring executor [\#97](https://github.com/tumugi/tumugi/pull/97) ([hakobera](https://github.com/hakobera))
|
34
|
+
- Update README [\#94](https://github.com/tumugi/tumugi/pull/94) ([hakobera](https://github.com/hakobera))
|
35
|
+
- Test with jruby 9.1.2.0 on travis [\#91](https://github.com/tumugi/tumugi/pull/91) ([hakobera](https://github.com/hakobera))
|
36
|
+
- Add command to create plugin template project [\#90](https://github.com/tumugi/tumugi/pull/90) ([hakobera](https://github.com/hakobera))
|
37
|
+
- Improve log [\#89](https://github.com/tumugi/tumugi/pull/89) ([hakobera](https://github.com/hakobera))
|
38
|
+
- Add plugin test helper [\#86](https://github.com/tumugi/tumugi/pull/86) ([hakobera](https://github.com/hakobera))
|
39
|
+
- Parameter can be set by block [\#85](https://github.com/tumugi/tumugi/pull/85) ([hakobera](https://github.com/hakobera))
|
40
|
+
|
41
|
+
## [v0.5.3](https://github.com/tumugi/tumugi/tree/v0.5.3) (2016-06-14)
|
42
|
+
[Full Changelog](https://github.com/tumugi/tumugi/compare/v0.5.2...v0.5.3)
|
5
43
|
|
6
44
|
**Fixed bugs:**
|
7
45
|
|
8
46
|
- Fix logger not defiend in Tumugi::Config [\#79](https://github.com/tumugi/tumugi/pull/79) ([hakobera](https://github.com/hakobera))
|
9
47
|
|
48
|
+
**Merged pull requests:**
|
49
|
+
|
50
|
+
- Preapre release for 0.5.3 [\#80](https://github.com/tumugi/tumugi/pull/80) ([hakobera](https://github.com/hakobera))
|
51
|
+
|
10
52
|
## [v0.5.2](https://github.com/tumugi/tumugi/tree/v0.5.2) (2016-06-13)
|
11
53
|
[Full Changelog](https://github.com/tumugi/tumugi/compare/v0.5.1...v0.5.2)
|
12
54
|
|
data/README.md
CHANGED
@@ -1,102 +1,16 @@
|
|
1
1
|
[](https://travis-ci.org/tumugi/tumugi) [](https://codeclimate.com/github/tumugi/tumugi) [](https://coveralls.io/github/tumugi/tumugi?branch=master) [](https://badge.fury.io/rb/tumugi)
|
2
2
|
|
3
|
+

|
4
|
+
|
3
5
|
# Tumugi
|
4
6
|
|
5
7
|
Tumugi is a ruby library to build, run and manage complex workflows. Tumugi enables you to define workflows as a ruby code.
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
-
**Tumugi only support Ruby 2.1 and above**
|
10
|
-
|
11
|
-
Add this line to your application's Gemfile:
|
12
|
-
|
13
|
-
```ruby
|
14
|
-
gem 'tumugi'
|
15
|
-
```
|
16
|
-
|
17
|
-
And then execute:
|
18
|
-
|
19
|
-
```bash
|
20
|
-
$ bundle
|
21
|
-
```
|
22
|
-
|
23
|
-
Or install it yourself as:
|
24
|
-
|
25
|
-
```bash
|
26
|
-
$ gem install tumugi
|
27
|
-
```
|
28
|
-
|
29
|
-
## Usage
|
30
|
-
|
31
|
-

|
40
|
-
|
41
|
-
You can define workflow above as ruby code:
|
42
|
-
|
43
|
-
```rb
|
44
|
-
task :task1 do
|
45
|
-
requires [:task2, :task3]
|
46
|
-
run { puts 'task1#run' }
|
47
|
-
end
|
48
|
-
|
49
|
-
task :task2 do
|
50
|
-
requires [:task4]
|
51
|
-
run { puts 'task2#run' }
|
52
|
-
end
|
53
|
-
|
54
|
-
task :task3 do
|
55
|
-
requires [:task4]
|
56
|
-
run { puts 'task3#run' }
|
57
|
-
end
|
58
|
-
|
59
|
-
task :task4 do
|
60
|
-
# You can use do ... end style
|
61
|
-
run do
|
62
|
-
puts 'task4#run'
|
63
|
-
sleep 3
|
64
|
-
end
|
65
|
-
end
|
66
|
-
```
|
9
|
+
**Tumugi only support Ruby >= 2.1 and JRuby >= 9.0.0.0**
|
67
10
|
|
68
|
-
|
69
|
-
then run this script by `tumugi` command like this:
|
11
|
+
## [Documentation](https://tumugi.github.io)
|
70
12
|
|
71
|
-
|
72
|
-
$ tumugi run -f workflow.rb task1
|
73
|
-
I, [2016-05-06T22:58:28.271234 #76156] INFO -- : start: task4
|
74
|
-
I, [2016-05-06T22:58:28.271310 #76156] INFO -- : run: task4
|
75
|
-
I, [2016-05-06T22:58:28.271386 #76156] INFO -- : task4#run
|
76
|
-
I, [2016-05-06T22:58:29.276218 #76156] INFO -- : completed: task4
|
77
|
-
I, [2016-05-06T22:58:29.276373 #76156] INFO -- : start: task2
|
78
|
-
I, [2016-05-06T22:58:29.276437 #76156] INFO -- : run: task2
|
79
|
-
I, [2016-05-06T22:58:29.276546 #76156] INFO -- : task2#run
|
80
|
-
I, [2016-05-06T22:58:29.276606 #76156] INFO -- : completed: task2
|
81
|
-
I, [2016-05-06T22:58:29.276650 #76156] INFO -- : start: task3
|
82
|
-
I, [2016-05-06T22:58:29.276688 #76156] INFO -- : run: task3
|
83
|
-
I, [2016-05-06T22:58:29.276733 #76156] INFO -- : task3#run
|
84
|
-
I, [2016-05-06T22:58:29.276765 #76156] INFO -- : completed: task3
|
85
|
-
I, [2016-05-06T22:58:29.276798 #76156] INFO -- : start: task1
|
86
|
-
I, [2016-05-06T22:58:29.276823 #76156] INFO -- : run: task1
|
87
|
-
I, [2016-05-06T22:58:29.276861 #76156] INFO -- : task1#run
|
88
|
-
I, [2016-05-06T22:58:29.276899 #76156] INFO -- : completed: task1
|
89
|
-
I, [2016-05-06T22:58:29.278919 #76156] INFO -- : Result report:
|
90
|
-
+-------+----------+------------+-----------+
|
91
|
-
| Task | Requires | Parameters | State |
|
92
|
-
+-------+----------+------------+-----------+
|
93
|
-
| task1 | task2 | | completed |
|
94
|
-
| | task3 | | |
|
95
|
-
| task3 | task4 | | completed |
|
96
|
-
| task2 | task4 | | completed |
|
97
|
-
| task4 | | | completed |
|
98
|
-
+-------+----------+------------+-----------+
|
99
|
-
```
|
13
|
+
Please check [tumugi.github.io](https://tumugi.github.io) for installation & usage.
|
100
14
|
|
101
15
|
## Development
|
102
16
|
|
data/Rakefile
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
require "rake/testtask"
|
3
|
-
require "github_changelog_generator/task"
|
4
3
|
|
5
4
|
Rake::TestTask.new(:test) do |t|
|
6
5
|
t.libs << "test"
|
@@ -8,7 +7,4 @@ Rake::TestTask.new(:test) do |t|
|
|
8
7
|
t.test_files = FileList['test/**/*_test.rb']
|
9
8
|
end
|
10
9
|
|
11
|
-
GitHubChangelogGenerator::RakeTask.new :changelog do |config|
|
12
|
-
end
|
13
|
-
|
14
10
|
task :default => :test
|
@@ -1,12 +1,15 @@
|
|
1
1
|
class FileTask < Tumugi::Task
|
2
2
|
Tumugi::Plugin.register_task(:file, self)
|
3
3
|
|
4
|
+
param :param1, type: :string
|
5
|
+
|
4
6
|
def output
|
5
7
|
target(:local_file, "tmp/#{id}.txt")
|
6
8
|
end
|
7
9
|
|
8
10
|
def run
|
9
11
|
log "#{id}#run"
|
12
|
+
log param1
|
10
13
|
output.open('w') do |f|
|
11
14
|
f.puts('done')
|
12
15
|
end
|
@@ -16,16 +19,22 @@ end
|
|
16
19
|
# Task type can specified by task plugin ID
|
17
20
|
task :task1, type: :file do
|
18
21
|
requires [:task2, :task3]
|
22
|
+
param1 'param1 of task1'
|
19
23
|
end
|
20
24
|
|
21
25
|
task :task2, type: :file do
|
22
26
|
requires [:task4]
|
27
|
+
param1 'param1 of task2'
|
23
28
|
end
|
24
29
|
|
25
30
|
# You can also specify type by Class object
|
26
31
|
task :task3, type: FileTask do
|
27
32
|
requires [:task4]
|
33
|
+
param1 'param1 of task3'
|
28
34
|
end
|
29
35
|
|
30
36
|
task :task4, type: FileTask do
|
37
|
+
param1 do
|
38
|
+
'param1 of task4'
|
39
|
+
end
|
31
40
|
end
|
data/examples/task_parameter.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
task :task1 do
|
2
|
-
param :key1, auto_bind: true, required: true #=>
|
2
|
+
param :key1, auto_bind: true, required: true #=> get value from CLI parameter
|
3
3
|
|
4
4
|
requires :task2
|
5
5
|
run do
|
@@ -8,10 +8,9 @@ task :task1 do
|
|
8
8
|
end
|
9
9
|
|
10
10
|
task :task2 do
|
11
|
-
|
12
|
-
param :
|
13
|
-
|
14
|
-
param_set :key2, 'value2' #=> 'value'
|
11
|
+
param :key1
|
12
|
+
param :key2, type: :time
|
13
|
+
key2 Time.parse('2016-06-27')
|
15
14
|
|
16
15
|
requires :task3
|
17
16
|
run do
|
data/lib/tumugi.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'tumugi/
|
1
|
+
require 'tumugi/workflow'
|
2
2
|
require 'tumugi/config'
|
3
3
|
require 'tumugi/error'
|
4
4
|
require 'tumugi/logger'
|
@@ -6,9 +6,12 @@ require 'tumugi/version'
|
|
6
6
|
|
7
7
|
module Tumugi
|
8
8
|
class << self
|
9
|
-
def
|
10
|
-
@
|
9
|
+
def workflow
|
10
|
+
@workflow ||= Tumugi::Workflow.new
|
11
11
|
end
|
12
|
+
# alias for backward compatibility
|
13
|
+
alias_method :app, :workflow
|
14
|
+
alias_method :application, :workflow
|
12
15
|
|
13
16
|
def configure(&block)
|
14
17
|
raise Tumugi::ConfigError.new 'Tumugi.configure must have block' unless block_given?
|
data/lib/tumugi/cli.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'thor'
|
2
2
|
require 'tumugi'
|
3
|
+
require 'tumugi/command/new'
|
3
4
|
|
4
5
|
module Tumugi
|
5
6
|
class CLI < Thor
|
@@ -12,6 +13,7 @@ module Tumugi
|
|
12
13
|
option :params, aliases: '-p', type: :hash, desc: 'Task parameters'
|
13
14
|
option :quiet, type: :boolean, desc: 'Suppress log', default: false
|
14
15
|
option :verbose, type: :boolean, desc: 'Show verbose log', default: false
|
16
|
+
option :log_format, type: :string, desc: 'Log format', enum: ['text', 'json'], default: 'text'
|
15
17
|
end
|
16
18
|
|
17
19
|
def exit_on_failure?
|
@@ -43,20 +45,43 @@ module Tumugi
|
|
43
45
|
execute(:show, task, opts.freeze)
|
44
46
|
end
|
45
47
|
|
48
|
+
desc "new PLUGIN_NAME", "Create new plugin project"
|
49
|
+
def new(name)
|
50
|
+
generate_plugin(name, options)
|
51
|
+
end
|
52
|
+
|
46
53
|
private
|
47
54
|
|
48
55
|
def execute(command, task, options)
|
49
|
-
success = Tumugi.
|
56
|
+
success = Tumugi.workflow.execute(command, task, options)
|
50
57
|
unless success
|
51
|
-
|
52
|
-
raise Thor::Error, 'failed'
|
58
|
+
raise Thor::Error, "execute finished, but return it's failed"
|
53
59
|
end
|
54
|
-
success
|
60
|
+
logger.info "status: success, command: #{command}, task: #{task}, options: #{options}"
|
55
61
|
rescue => e
|
56
62
|
logger.error "#{command} command failed"
|
57
63
|
logger.error e.message
|
58
|
-
|
59
|
-
|
64
|
+
if options[:verbose]
|
65
|
+
e.backtrace.each { |line| logger.debug line }
|
66
|
+
else
|
67
|
+
logger.error "If you want to know more detail, run with '--verbose' option"
|
68
|
+
end
|
69
|
+
logger.error "status: failed, command: #{command}, task: #{task}, options: #{options}"
|
70
|
+
raise Thor::Error.new("tumugi #{command} failed, please check log")
|
71
|
+
end
|
72
|
+
|
73
|
+
def generate_plugin(name, options)
|
74
|
+
Tumugi::Command::New.new.execute(name, options)
|
75
|
+
logger.info "status: success, command: new, name: #{name}, options: #{options}"
|
76
|
+
rescue => e
|
77
|
+
logger.error e.message
|
78
|
+
if options[:verbose]
|
79
|
+
e.backtrace.each { |line| logger.debug line }
|
80
|
+
else
|
81
|
+
logger.error "If you want to know more detail, run with '--verbose' option"
|
82
|
+
end
|
83
|
+
logger.error "status: failed, command: new, name: #{name}, options: #{options}"
|
84
|
+
raise Thor::Error.new("tumugi new failed, please check log")
|
60
85
|
end
|
61
86
|
|
62
87
|
def logger
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'erubis'
|
3
|
+
|
4
|
+
module Tumugi
|
5
|
+
module Command
|
6
|
+
class New
|
7
|
+
def execute(name, options={})
|
8
|
+
full_project_name = "tumugi-plugin-#{name}"
|
9
|
+
templates = [
|
10
|
+
[ "Gemfile.erb", "Gemfile" ],
|
11
|
+
[ "gemspec.erb", "#{full_project_name}.gemspec" ],
|
12
|
+
[ "gitignore.erb", ".gitignore" ],
|
13
|
+
[ "Rakefile.erb", "Rakefile" ],
|
14
|
+
[ "README.md.erb", "README.md" ],
|
15
|
+
[ "examples/example.rb.erb", "examples/example.rb" ],
|
16
|
+
[ "lib/tumugi/plugin/target/target.rb.erb", "lib/tumugi/plugin/target/#{name}.rb" ],
|
17
|
+
[ "lib/tumugi/plugin/task/task.rb.erb", "lib/tumugi/plugin/task/#{name}.rb" ],
|
18
|
+
[ "test/test_helper.rb.erb", "test/test_helper.rb" ],
|
19
|
+
[ "test/test.rb.erb", "test/#{name}_test.rb" ],
|
20
|
+
[ "test/plugin/target/target_test.rb.erb", "test/plugin/target/#{name}_test.rb" ],
|
21
|
+
[ "test/plugin/task/task_test.rb.erb", "test/plugin/task/#{name}_test.rb" ],
|
22
|
+
]
|
23
|
+
|
24
|
+
@data_dir = "#{File.expand_path(File.dirname(__FILE__))}/../data/new"
|
25
|
+
@dest_dir = "#{(options[:path] || '.')}/#{full_project_name}"
|
26
|
+
if File.exist?(@dest_dir)
|
27
|
+
logger.error("#{@dest_dir} is already exists. Please delete it first")
|
28
|
+
return false
|
29
|
+
end
|
30
|
+
|
31
|
+
FileUtils.mkdir_p(@dest_dir)
|
32
|
+
|
33
|
+
templates.each do |value|
|
34
|
+
src_file, dest_file = value
|
35
|
+
eruby = Erubis::Eruby.new(File.read(src_path(src_file)))
|
36
|
+
eruby.filename = src_path(src_file)
|
37
|
+
context = {
|
38
|
+
full_project_name: full_project_name,
|
39
|
+
name: name,
|
40
|
+
tumugi_version: Tumugi::VERSION,
|
41
|
+
}
|
42
|
+
logger.info("Create #{dest_path(dest_file)}")
|
43
|
+
FileUtils.mkdir_p(File.dirname(dest_path(dest_file)))
|
44
|
+
File.write(dest_path(dest_file), eruby.result(context))
|
45
|
+
end
|
46
|
+
return true
|
47
|
+
end
|
48
|
+
|
49
|
+
def logger
|
50
|
+
Tumugi::Logger.instance
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def src_path(file)
|
56
|
+
"#{@data_dir}/#{file}"
|
57
|
+
end
|
58
|
+
|
59
|
+
def dest_path(file)
|
60
|
+
"#{@dest_dir}/#{file}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/tumugi/command/run.rb
CHANGED
@@ -1,120 +1,30 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
require 'terminal-table'
|
4
|
-
require 'thor'
|
5
|
-
require 'timeout'
|
6
|
-
|
7
|
-
require 'tumugi/error'
|
8
|
-
require 'tumugi/mixin/listable'
|
1
|
+
require 'tumugi/dag_result_reporter'
|
2
|
+
require 'tumugi/executor/local_executor'
|
9
3
|
|
10
4
|
module Tumugi
|
11
5
|
module Command
|
12
6
|
class Run
|
13
|
-
include Tumugi::Mixin::Listable
|
14
|
-
|
15
7
|
def execute(dag, options={})
|
16
|
-
|
17
|
-
|
18
|
-
start(
|
8
|
+
worker_num = options[:workers] || Tumugi.config.workers
|
9
|
+
executor = Tumugi::Executor::LocalExecutor.new(dag, logger, worker_num: worker_num)
|
10
|
+
result = start(executor)
|
19
11
|
show_result_report(dag)
|
20
|
-
|
12
|
+
result
|
21
13
|
end
|
22
14
|
|
23
15
|
private
|
24
16
|
|
25
|
-
def
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
available_task_queue << t
|
31
|
-
else
|
32
|
-
waiting_task_queue << t
|
33
|
-
end
|
34
|
-
end
|
35
|
-
lambda {
|
36
|
-
task = (available_task_queue.empty? ? nil : available_task_queue.pop)
|
37
|
-
if task.nil?
|
38
|
-
task = (waiting_task_queue.empty? ? nil : waiting_task_queue.pop)
|
39
|
-
end
|
40
|
-
task || Parallel::Stop
|
41
|
-
}
|
42
|
-
end
|
43
|
-
|
44
|
-
def start(proc, settings)
|
45
|
-
Parallel.each(proc, settings) do |t|
|
46
|
-
logger.info "start: #{t.id}"
|
47
|
-
timeout = t.timeout || Tumugi.config.timeout
|
48
|
-
Timeout::timeout(timeout, Tumugi::TimeoutError) do
|
49
|
-
until t.ready? || t.requires_failed?
|
50
|
-
sleep 5
|
51
|
-
end
|
52
|
-
|
53
|
-
if t.completed?
|
54
|
-
t.state = :skipped
|
55
|
-
logger.info "#{t.state}: #{t.id} is already completed"
|
56
|
-
elsif t.requires_failed?
|
57
|
-
t.state = :requires_failed
|
58
|
-
logger.info "#{t.state}: #{t.id} has failed requires task"
|
59
|
-
else
|
60
|
-
logger.info "run: #{t.id}"
|
61
|
-
t.state = :running
|
62
|
-
|
63
|
-
begin
|
64
|
-
Retriable.retriable retry_options do
|
65
|
-
t.run
|
66
|
-
end
|
67
|
-
rescue => e
|
68
|
-
t.state = :failed
|
69
|
-
logger.info "#{t.state}: #{t.id}"
|
70
|
-
logger.error "#{e.message}"
|
71
|
-
logger.error e.backtrace.join("\n")
|
72
|
-
else
|
73
|
-
t.state = :completed
|
74
|
-
logger.info "#{t.state}: #{t.id}"
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def retry_options
|
82
|
-
{
|
83
|
-
tries: Tumugi.config.max_retry,
|
84
|
-
base_interval: Tumugi.config.retry_interval,
|
85
|
-
max_interval: Tumugi.config.retry_interval * Tumugi.config.max_retry,
|
86
|
-
max_elapsed_time: Tumugi.config.retry_interval * Tumugi.config.max_retry,
|
87
|
-
multiplier: 1.0,
|
88
|
-
rand_factor: 0.0,
|
89
|
-
on_retry: on_retry
|
90
|
-
}
|
91
|
-
end
|
92
|
-
|
93
|
-
def on_retry
|
94
|
-
Proc.new do |exception, try, elapsed_time, next_interval|
|
95
|
-
if next_interval
|
96
|
-
logger.error "#{exception.class}: '#{exception.message}' - #{try} tries in #{elapsed_time} seconds and #{next_interval} seconds until the next try."
|
97
|
-
else
|
98
|
-
logger.error "#{exception.class}: '#{exception.message}' - #{try} tries in #{elapsed_time} seconds. Task failed."
|
99
|
-
end
|
100
|
-
end
|
17
|
+
def start(executor)
|
18
|
+
logger.info "start workflow: #{Tumugi.workflow.id}"
|
19
|
+
result = executor.execute
|
20
|
+
logger.info "end workflow: #{Tumugi.workflow.id}"
|
21
|
+
result
|
101
22
|
end
|
102
23
|
|
103
24
|
def show_result_report(dag)
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
proxy = task.class.merged_parameter_proxy
|
108
|
-
requires = list(task.requires).map do |r|
|
109
|
-
r.id
|
110
|
-
end
|
111
|
-
params = proxy.params.map do |name, _|
|
112
|
-
"#{name}=#{task.send(name.to_sym)}"
|
113
|
-
end
|
114
|
-
t << [ task.id, requires.join("\n"), params.join("\n"), task.state ]
|
115
|
-
end
|
116
|
-
end
|
117
|
-
logger.info "Result report:\n#{table.to_s}"
|
25
|
+
reporter = Tumugi::DAGResultReporter.new
|
26
|
+
report = reporter.show(dag)
|
27
|
+
logger.info "Result report:\n#{report.to_s}"
|
118
28
|
end
|
119
29
|
|
120
30
|
def logger
|