pwrake 0.9.9.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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"