pwrake 0.9.9.2 → 2.0.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.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/CHANGES_V2.md +90 -0
  4. data/{LICENSE.txt → MIT-LICENSE} +2 -3
  5. data/README +12 -0
  6. data/README.md +75 -52
  7. data/bin/gfwhere-pipe +23 -12
  8. data/bin/pwrake +22 -29
  9. data/bin/pwrake_branch +24 -0
  10. data/lib/pwrake/branch.rb +22 -0
  11. data/lib/pwrake/branch/branch.rb +213 -0
  12. data/lib/pwrake/branch/branch_application.rb +53 -0
  13. data/lib/pwrake/branch/fiber_queue.rb +36 -0
  14. data/lib/pwrake/branch/file_utils.rb +101 -0
  15. data/lib/pwrake/branch/shell.rb +231 -0
  16. data/lib/pwrake/{profiler.rb → branch/shell_profiler.rb} +28 -27
  17. data/lib/pwrake/branch/worker_communicator.rb +104 -0
  18. data/lib/pwrake/{gfarm_feature.rb → gfarm/gfarm_path.rb} +2 -100
  19. data/lib/pwrake/gfarm/gfarm_postprocess.rb +53 -0
  20. data/lib/pwrake/iomux/channel.rb +70 -0
  21. data/lib/pwrake/iomux/handler.rb +124 -0
  22. data/lib/pwrake/iomux/handler_set.rb +35 -0
  23. data/lib/pwrake/iomux/runner.rb +62 -0
  24. data/lib/pwrake/logger.rb +3 -150
  25. data/lib/pwrake/master.rb +30 -137
  26. data/lib/pwrake/master/fiber_pool.rb +69 -0
  27. data/lib/pwrake/master/idle_cores.rb +30 -0
  28. data/lib/pwrake/master/master.rb +345 -0
  29. data/lib/pwrake/master/master_application.rb +150 -0
  30. data/lib/pwrake/master/postprocess.rb +16 -0
  31. data/lib/pwrake/{graphviz.rb → misc/graphviz.rb} +0 -0
  32. data/lib/pwrake/{mcgp.rb → misc/mcgp.rb} +63 -42
  33. data/lib/pwrake/option/host_map.rb +158 -0
  34. data/lib/pwrake/option/option.rb +357 -0
  35. data/lib/pwrake/option/option_filesystem.rb +112 -0
  36. data/lib/pwrake/queue/locality_aware_queue.rb +158 -0
  37. data/lib/pwrake/queue/no_action_queue.rb +67 -0
  38. data/lib/pwrake/queue/queue_array.rb +366 -0
  39. data/lib/pwrake/queue/task_queue.rb +164 -0
  40. data/lib/pwrake/report.rb +1 -0
  41. data/lib/pwrake/report/parallelism.rb +9 -3
  42. data/lib/pwrake/report/report.rb +50 -103
  43. data/lib/pwrake/report/task_stat.rb +83 -0
  44. data/lib/pwrake/task/task_algorithm.rb +107 -0
  45. data/lib/pwrake/task/task_manager.rb +32 -0
  46. data/lib/pwrake/task/task_property.rb +98 -0
  47. data/lib/pwrake/task/task_rank.rb +48 -0
  48. data/lib/pwrake/task/task_wrapper.rb +296 -0
  49. data/lib/pwrake/version.rb +1 -1
  50. data/lib/pwrake/worker/executor.rb +169 -0
  51. data/lib/pwrake/worker/gfarm_directory.rb +90 -0
  52. data/lib/pwrake/worker/invoker.rb +199 -0
  53. data/lib/pwrake/worker/load.rb +14 -0
  54. data/lib/pwrake/worker/log_executor.rb +73 -0
  55. data/lib/pwrake/worker/shared_directory.rb +74 -0
  56. data/lib/pwrake/worker/worker_main.rb +14 -0
  57. data/lib/pwrake/worker/writer.rb +59 -0
  58. data/setup.rb +1212 -1502
  59. data/spec/003/Rakefile +2 -2
  60. data/spec/008/Rakefile +2 -1
  61. data/spec/009/Rakefile +1 -1
  62. data/spec/009/pwrake_conf.yaml +1 -3
  63. data/spec/hosts +0 -2
  64. data/spec/pwrake_spec.rb +9 -8
  65. metadata +50 -21
  66. data/lib/pwrake.rb +0 -19
  67. data/lib/pwrake/application.rb +0 -232
  68. data/lib/pwrake/counter.rb +0 -54
  69. data/lib/pwrake/file_utils.rb +0 -98
  70. data/lib/pwrake/gfwhere_pool.rb +0 -109
  71. data/lib/pwrake/host_list.rb +0 -88
  72. data/lib/pwrake/locality_aware_queue.rb +0 -413
  73. data/lib/pwrake/option.rb +0 -400
  74. data/lib/pwrake/rake_modify.rb +0 -14
  75. data/lib/pwrake/shell.rb +0 -186
  76. data/lib/pwrake/task_algorithm.rb +0 -475
  77. data/lib/pwrake/task_queue.rb +0 -633
  78. data/lib/pwrake/timer.rb +0 -22
@@ -0,0 +1,124 @@
1
+ module Pwrake
2
+
3
+ class Handler
4
+
5
+ def initialize(runner,*io,&blk)
6
+ if !runner.kind_of?(Runner)
7
+ raise TypeError, "Argument must be Runner but #{runner.class}"
8
+ end
9
+ @runner = runner
10
+ @channel = {}
11
+ if !io.empty?
12
+ if !block_given?
13
+ @ior,@iow,@ioe = *io
14
+ end
15
+ else
16
+ if block_given?
17
+ @ior,w0 = IO.pipe
18
+ @ioe,w1 = IO.pipe
19
+ r2,@iow = IO.pipe
20
+ yield(w0,w1,r2)
21
+ end
22
+ end
23
+ if @ior.nil? && @iow.nil?
24
+ raise "fail to initialize IO"
25
+ end
26
+ end
27
+
28
+ attr_reader :runner, :ior, :iow, :ioe
29
+ attr_accessor :host
30
+
31
+ def add_channel(chan)
32
+ if !chan.kind_of?(Channel)
33
+ raise TypeError, "Argument must be Channel but #{chan.class}"
34
+ end
35
+ @channel[chan.id] = chan
36
+ @runner.add_handler(self)
37
+ end
38
+
39
+ def delete_channel(chan)
40
+ if !chan.kind_of?(Channel)
41
+ raise TypeError, "Argument must be Channel but #{chan.class}"
42
+ end
43
+ @channel.delete(chan.id)
44
+ if @channel.empty?
45
+ @runner.delete_handler(self)
46
+ end
47
+ end
48
+
49
+ def process_line
50
+ if s = (@ior.eof?) ? nil : @ior.gets
51
+ default_channel = @channel[nil]
52
+ if @channel.size > ((default_channel) ? 1 : 0)
53
+ if /^(\d+):(.*)$/ =~ s
54
+ ch,line = $1,$2
55
+ if chan = @channel[ch.to_i]
56
+ return chan.run_fiber(line)
57
+ else
58
+ raise "No channel##{ch}"
59
+ end
60
+ end
61
+ end
62
+ if default_channel
63
+ return default_channel.run_fiber(s.chomp)
64
+ else
65
+ raise "No default_channel"
66
+ end
67
+ else
68
+ # End of IO
69
+ @channel.values.each do |chan|
70
+ if chan.fiber
71
+ chan.run_fiber(nil)
72
+ end
73
+ end
74
+ end
75
+ end
76
+
77
+ def finish
78
+ @channel.values.each do |chan|
79
+ chan.finish
80
+ end
81
+ end
82
+
83
+ # -- writer
84
+
85
+ def put_line(line)
86
+ begin
87
+ @iow.print line.to_str+"\n"
88
+ @iow.flush
89
+ #Log.debug "Handler#put_line #{line.inspect} @iow=#{@iow.inspect}"
90
+ rescue Errno::EPIPE => e
91
+ if Rake.application.options.debug
92
+ $stderr.puts "Errno::EPIPE in #{self.class}.put_line '#{line.chomp}'"
93
+ $stderr.puts e.backtrace.join("\n")
94
+ end
95
+ Log.error "Errno::EPIPE in #{self.class}.put_line '#{line.chomp}'\n"+
96
+ e.backtrace.join("\n")
97
+ #raise e
98
+ end
99
+ end
100
+
101
+ def puts(line)
102
+ @iow.puts(line)
103
+ end
104
+
105
+ def gets
106
+ @ior.gets
107
+ end
108
+
109
+ def wait_message(end_msg)
110
+ if line = @ior.gets
111
+ line.chomp!
112
+ m = "Handler#wait_message: #{line} host=#{@host}"
113
+ if line == end_msg
114
+ Log.debug m
115
+ else
116
+ Log.error m
117
+ end
118
+ else
119
+ Log.error "Handler#wait_message: fail to read @ior"
120
+ end
121
+ end
122
+
123
+ end
124
+ end
@@ -0,0 +1,35 @@
1
+ module Pwrake
2
+
3
+ class HandlerSet < Array
4
+
5
+ def kill(sig)
6
+ each do |hdl|
7
+ hdl.iow.puts("kill:#{sig}")
8
+ hdl.iow.flush
9
+ end
10
+ end
11
+
12
+ def exit
13
+ a = []
14
+ each do |hdl|
15
+ iow = hdl.iow
16
+ begin
17
+ iow.puts "exit"
18
+ iow.flush
19
+ a << hdl
20
+ Log.debug "HandlerSet#exit iow=#{iow.inspect}"
21
+ rescue Errno::EPIPE => e
22
+ if Rake.application.options.debug
23
+ $stderr.puts "Errno::EPIPE in #{self.class}.exit iow=#{iow.inspect}"
24
+ $stderr.puts e.backtrace.join("\n")
25
+ end
26
+ Log.error "Errno::EPIPE in #{self.class}.exit iow=#{iow.inspect}\n"+
27
+ e.backtrace.join("\n")
28
+ end
29
+ end
30
+ a.each{|hdl| hdl.wait_message("exited")}
31
+ Log.debug "HandlerSet#exit end"
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,62 @@
1
+ module Pwrake
2
+
3
+ class TimeoutError < IOError; end
4
+
5
+ class Runner
6
+
7
+ def initialize(timeout=nil)
8
+ @timeout = timeout
9
+ @handler = {}
10
+ @hb_time = {}
11
+ end
12
+
13
+ attr_reader :handler
14
+
15
+ def add_handler(hdl)
16
+ @handler[hdl.ior] ||= hdl
17
+ end
18
+
19
+ def delete_handler(hdl)
20
+ @handler.delete(hdl.ior)
21
+ end
22
+
23
+ def run
24
+ while !(io_set = @handler.keys).empty?
25
+ sel, = IO.select(io_set,nil,nil,@timeout)
26
+ if sel.nil?
27
+ raise TimeoutError,"Timeout (#{@timeout} s) in IO.select"
28
+ end
29
+ sel.each do |io|
30
+ @handler[io].process_line
31
+ end
32
+ if @timeout && @hb_earliest
33
+ if Time.now - @hb_earliest > @timeout
34
+ io = @hb_time.key(@hb_earliest)
35
+ raise TimeoutError,"Timeout (#{@timeout}s) "+
36
+ "in Heartbeat from host=#{get_host(io)}"
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ def finish
43
+ @handler.each do |io,hdl|
44
+ hdl.finish
45
+ end
46
+ end
47
+
48
+ # used to print an error message
49
+ def get_host(io)
50
+ hdl = @handler[io]
51
+ h = hdl.respond_to?(:host) ? hdl.host : nil
52
+ end
53
+
54
+ # called when IO start and receive heartbeat
55
+ def heartbeat(io)
56
+ @hb_time[io] = Time.now
57
+ @hb_earliest = @hb_time.values.min
58
+ #Log.debug "heartbeat: host=#{get_host(io)}"
59
+ end
60
+
61
+ end
62
+ end
@@ -1,159 +1,12 @@
1
1
  module Pwrake
2
2
 
3
- LOCK = Mutex.new
4
-
5
- class Logger
6
-
7
- attr_accessor :level
8
-
9
- module Severity
10
- # Low-level information, mostly for developers
11
- DEBUG = 0
12
- INFO = 1
13
- WARN = 2
14
- ERROR = 3
15
- FATAL = 4
16
- UNKNOWN = 5
17
- end
18
- include Severity
19
-
20
- def initialize
21
- @level = WARN
22
- @out = nil
23
- @filename = nil
24
- @lock = Mutex.new
25
- end
26
-
27
- def open(file)
28
- close if @out
29
- case file
30
- when IO
31
- @out = file
32
- @filename = nil
33
- when String
34
- @out = File.open(file,"w")
35
- @filename = file
36
- else
37
- raise "file arg must be IO or String"
38
- end
39
- @start_time = Time.now
40
- info "LogStart=" + fmt_time(@start_time)
41
- info "logfile=#{@filename}" if @filename
42
- end
43
-
44
- def finish(str, start_time)
45
- if @out
46
- finish_time = Time.now
47
- t1 = Log.fmt_time(start_time)
48
- t2 = Log.fmt_time(finish_time)
49
- elap = finish_time - start_time
50
- info "#{str} : start=#{t1} end=#{t2} elap=#{elap}"
51
- end
52
- end
53
-
54
- def add(severity, message)
55
- if !severity || severity >= @level
56
- if @out
57
- @lock.synchronize do
58
- @out.write(message+"\n")
59
- end
60
- else
61
- LOCK.synchronize do
62
- $stderr.write(message+"\n")
63
- end
64
- end
65
- end
66
- true
67
- end
68
- alias log add
69
-
70
- def info(msg)
71
- add(INFO, msg)
72
- end
73
-
74
- def debug(msg)
75
- add(DEBUG, msg)
76
- end
77
-
78
- def warn(msg)
79
- add(WARN, msg)
80
- end
81
-
82
- def fmt_time(t)
83
- t.strftime("%Y-%m-%dT%H:%M:%S.%%06d") % t.usec
84
- end
85
-
86
- def timer(prefix,*args)
87
- Timer.new(prefix,*args)
88
- end
89
-
90
- def close
91
- finish "LogEnd", @start_time
92
- @lock.synchronize do
93
- @out.close if @filename
94
- @out=nil
95
- end
96
- @filename=nil
97
- end
98
-
99
- end # class Logger
100
-
101
-
102
- LOGGER = Logger.new
103
-
104
3
  module Log
105
- include Logger::Severity
106
4
 
107
5
  module_function
108
6
 
109
- def open(file)
110
- LOGGER.open(file)
111
- end
112
-
113
- def close
114
- LOGGER.close
115
- end
116
-
117
- def info(s)
118
- LOGGER.info(s)
119
- end
120
-
121
- def debug(s)
122
- LOGGER.debug(s)
123
- end
124
-
125
- def warn(s)
126
- LOGGER.warn(s)
127
- end
128
-
129
- def level
130
- LOGGER.level
131
- end
132
-
133
- def level=(x)
134
- LOGGER.level = x
135
- end
136
-
137
- def fmt_time(t)
138
- t.strftime("%Y-%m-%dT%H:%M:%S.%%06d") % t.usec
139
- end
140
-
141
- def timer(prefix,*args)
142
- Timer.new(prefix,*args)
143
- end
144
-
145
- def stderr_puts(message)
146
- LOCK.synchronize do
147
- $stderr.write(message+"\n")
148
- end
149
- end
150
-
151
- def stdout_puts(message)
152
- LOCK.synchronize do
153
- $stdout.write(message+"\n")
154
- end
7
+ def method_missing(meth_id,*args)
8
+ Rake.application.logger.send(meth_id,*args)
155
9
  end
156
10
 
157
11
  end
158
-
159
- end # module Pwrake
12
+ end
@@ -1,137 +1,30 @@
1
- module Pwrake
2
-
3
- def current_shell
4
- Thread.current[:shell]
5
- end
6
-
7
- def current_shell=(a)
8
- Thread.current[:shell] = a
9
- Thread.current[:hint] = a.host
10
- end
11
-
12
- module_function :current_shell, :current_shell=
13
-
14
-
15
- class Master
16
- include Pwrake::Option
17
-
18
- attr_reader :task_queue
19
- attr_reader :finish_queue
20
- attr_reader :shell_set
21
- attr_reader :filesystem
22
- attr_reader :postprocess
23
-
24
- def initialize
25
- @started = false
26
- @lock = Mutex.new
27
- @current_task_id = -1
28
- end
29
-
30
- def init
31
- init_option # Pwrake::Option
32
- setup_option # Pwrake::Option
33
- end
34
-
35
- def start
36
- return if @task_queue
37
- timer = Timer.new("start_worker")
38
- @finish_queue = Queue.new
39
- @task_queue = @queue_class.new(host_list)
40
- @shell_set = (1..@num_noaction_threads).map{ NoActionShell.new }
41
- host_list.core_list.each_with_index do |h,i|
42
- @shell_set << @shell_class.new(h,@shell_opt)
43
- end
44
- start_threads
45
- timer.finish
46
- end
47
-
48
- def finish
49
- Log.debug "-- Master#finish called"
50
- @task_queue.finish if @task_queue
51
- @threads.each{|t| t.join } if @threads
52
- @counter.print if @counter
53
- finish_option # Pwrake::Option
54
- end
55
-
56
- def start_threads
57
- Thread.abort_on_exception = true
58
- @threads = []
59
- @exit_task = {}
60
- t_intvl = Pwrake.application.pwrake_options['THREAD_CREATE_INTERVAL']
61
- @shell_set.each do |c|
62
- tc0 = Time.now
63
- @threads << Thread.new(c) do |conn|
64
- Pwrake.current_shell = conn
65
- t0 = Time.now
66
- conn.start
67
- t = Time.now - t0
68
- Log.info "-- worker[#{conn.id}] connect to #{conn.host}: %.3f sec" % t
69
- begin
70
- thread_loop(conn)
71
- ensure
72
- Log.info "-- worker[#{conn.id}] ensure : closing #{conn.host}"
73
- conn.finish
74
- end
75
- end
76
- t_sleep = t_intvl - (Time.now - tc0)
77
- sleep t_sleep if t_sleep > 0
78
- end
79
- end
80
-
81
- def thread_loop(conn,last=nil)
82
- if last
83
- @exit_task[last] = Thread.current
84
- end
85
- hint = (conn) ? conn.host : nil
86
- standard_exception_handling do
87
- while true
88
- time_start = Time.now
89
- t = @task_queue.deq(hint)
90
- break if !t
91
- time_deq = Time.now - time_start
92
- Log.debug "--- Master#thread_loop deq t=#{t.inspect} time=#{time_deq}sec"
93
- t.pw_invoke
94
- if th = @exit_task.delete(t)
95
- @task_queue.thread_end(th)
96
- end
97
- end
98
- end
99
- end
100
-
101
- def task_id_counter
102
- @lock.synchronize do
103
- @current_task_id += 1
104
- end
105
- end
106
-
107
- # Provide standard execption handling for the given block.
108
- def standard_exception_handling
109
- begin
110
- yield
111
- rescue SystemExit => ex
112
- # Exit silently with current status
113
- @task_queue.stop
114
- raise
115
- rescue OptionParser::InvalidOption => ex
116
- # Exit silently
117
- @task_queue.stop
118
- exit(false)
119
- rescue Exception => ex
120
- # Exit with error message
121
- name = "pwrake"
122
- $stderr.puts "#{name} aborted!"
123
- $stderr.puts ex.message
124
- if Rake.application.options.trace
125
- $stderr.puts ex.backtrace.join("\n")
126
- else
127
- $stderr.puts ex.backtrace.find {|str| str =~ /#{@rakefile}/ } || ""
128
- $stderr.puts "(See full trace by running task with --trace)"
129
- end
130
- @task_queue.stop
131
- exit(false)
132
- end
133
- end
134
-
135
- end
136
-
137
- end # module Pwrake
1
+ require "fileutils"
2
+ require "pathname"
3
+ require "yaml"
4
+ require "logger"
5
+ require "csv"
6
+
7
+ require "pwrake/version"
8
+
9
+ require "pwrake/iomux/runner"
10
+ require "pwrake/iomux/handler"
11
+ require "pwrake/iomux/handler_set"
12
+ require "pwrake/iomux/channel"
13
+
14
+ require "pwrake/logger"
15
+ require "pwrake/master/master"
16
+ require "pwrake/master/idle_cores"
17
+ require "pwrake/master/master_application"
18
+ require "pwrake/master/fiber_pool"
19
+ require "pwrake/option/option"
20
+ require "pwrake/option/option_filesystem"
21
+ require "pwrake/option/host_map"
22
+ require "pwrake/queue/queue_array"
23
+ require "pwrake/queue/task_queue"
24
+ require "pwrake/queue/locality_aware_queue"
25
+ require "pwrake/queue/no_action_queue"
26
+ require "pwrake/task/task_algorithm"
27
+ require "pwrake/task/task_manager"
28
+ require "pwrake/task/task_wrapper"
29
+ require "pwrake/task/task_property"
30
+ require "pwrake/task/task_rank"