vete 0.2.0 → 0.3.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/lib/vete.rb +46 -27
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 31328c3602f1174d697b56c9d0b8049986b68151975ed05c2febe3bab04d0c00
|
4
|
+
data.tar.gz: e4d99dd8303a7bcc8d589f66bb6ad0a0e2b79bfb718c7f2856f2e3a7aa558e63
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0df917b8b8bb7cc72e0903130543e4e700b4264e8119b9f65d5c038cfa2dfb3538804945df489fcc27fa781deb18c923a2c540087dbf95b60c50f8a1eca48890
|
7
|
+
data.tar.gz: d05bac44008d71d71738b234d0d2f750fdfdaa4c5d3de24263dd72e1888039165c5d902bdb01510712e0741750ae57dca16a679728c9cf5e97384227d1af80b2
|
data/lib/vete.rb
CHANGED
@@ -4,6 +4,8 @@
|
|
4
4
|
# Author: Steve Shreeve (steve.shreeve@gmail.com)
|
5
5
|
# Date: Mar 21, 2023
|
6
6
|
# ============================================================================
|
7
|
+
# TODO: 1) progress should update until all workers have *finished*
|
8
|
+
# ============================================================================
|
7
9
|
|
8
10
|
STDOUT.sync = true
|
9
11
|
|
@@ -13,16 +15,20 @@ require "fileutils"
|
|
13
15
|
require "optparse"
|
14
16
|
require "thread"
|
15
17
|
|
16
|
-
|
18
|
+
@pid = Process.pid
|
19
|
+
|
20
|
+
trap("INT" ) { print clear + go; abort "\n" }
|
21
|
+
trap("WINCH") { print clear or draw if @pid == Process.pid }
|
17
22
|
|
18
23
|
OptionParser.new.instance_eval do
|
19
|
-
@version = "0.
|
24
|
+
@version = "0.3.0"
|
20
25
|
@banner = "usage: #{program_name} [options]"
|
21
26
|
|
22
27
|
on "-b", "--bar <width>" , "Progress bar width, in characters", Integer
|
23
28
|
on "-c", "--char <character>" , "Character to use for progress bar", String
|
24
|
-
on "-
|
29
|
+
on "-d", "--delay <mode>" , "Delay mode (rand, task, numeric)"
|
25
30
|
on "-h", "--help" , "Show help and command usage" do Kernel.abort to_s; end
|
31
|
+
on "-r", "--reset" , "Remove directory used for job processing and quit"
|
26
32
|
on "-v", "--version" , "Show version number" do Kernel.abort "#{program_name} #{@version}"; end
|
27
33
|
on "-w", "--workers <count>" , "Set the number of workers (default is 1)", Integer
|
28
34
|
|
@@ -31,10 +37,21 @@ end.parse!(into: opts={}) rescue abort($!.message)
|
|
31
37
|
|
32
38
|
# populate CLI options
|
33
39
|
@char = opts[:char ] || "•"; @char = @char[0]
|
40
|
+
@wait = opts[:delay ]
|
34
41
|
@nuke = opts[:reset ]
|
35
42
|
@wide = opts[:bar ] || 20
|
36
43
|
@work = opts[:workers] || 1
|
37
44
|
|
45
|
+
# handle wait mode
|
46
|
+
case @wait
|
47
|
+
when "rand", "task", nil
|
48
|
+
when /\A(?:0|[1-9]\d*|(?:0?\.|[1-9]\d*\.)\d*)\z/
|
49
|
+
@wait = @wait.to_f
|
50
|
+
@wait > 0 or abort "invalid delay time (#{@wait.to_f} secs)"
|
51
|
+
else
|
52
|
+
abort "invalid delay mode '#{@wait}'"
|
53
|
+
end
|
54
|
+
|
38
55
|
# define job directories
|
39
56
|
@vete = File.expand_path(".vete")
|
40
57
|
@todo = File.join(@vete, "todo")
|
@@ -42,7 +59,6 @@ end.parse!(into: opts={}) rescue abort($!.message)
|
|
42
59
|
@done = File.join(@vete, "done")
|
43
60
|
@bomb = File.join(@vete, "bomb")
|
44
61
|
|
45
|
-
|
46
62
|
def move(path, dest)
|
47
63
|
dest = File.join(dest, File.basename(path))
|
48
64
|
FileUtils.mv(path, dest, force: true, secure: true)
|
@@ -76,10 +92,10 @@ end
|
|
76
92
|
|
77
93
|
# https://www.cse.psu.edu/~kxc104/class/cmpen472/16f/hw/hw8/vt100ansi.htm
|
78
94
|
|
79
|
-
def clear
|
80
|
-
def cursor(on)
|
81
|
-
def go(r=1,c=1); "\e[#{r};#{c}H" ; end
|
82
|
-
def go!(...)
|
95
|
+
def clear(line=nil); line ? "\e[K" : "\e[2J" ; end
|
96
|
+
def cursor(on) ; print on ? "\e[?25h": "\e[?25l"; end
|
97
|
+
def go(r=1,c=1) ; "\e[#{r};#{c}H" ; end
|
98
|
+
def go!(...) ; print go(...) ; end
|
83
99
|
|
84
100
|
def fg(rgb=nil); rgb ? "\e[38;2;#{hx(rgb)}m" : "\e[39m"; end
|
85
101
|
def bg(rgb=nil); rgb ? "\e[48;2;#{hx(rgb)}m" : "\e[49m"; end
|
@@ -88,22 +104,22 @@ def hx(str=nil); str =~ /\A#?(?:(\h\h)(\h\h)(\h\h)|(\h)(\h)(\h))\z/ or return
|
|
88
104
|
[r.hex, g.hex, b.hex] * ";"
|
89
105
|
end
|
90
106
|
|
91
|
-
def draw(
|
107
|
+
def draw(live=0, done=0, bomb=0, jobs=0, info=nil)
|
92
108
|
|
93
109
|
# outer box
|
94
110
|
unless info
|
95
111
|
print [
|
96
112
|
clear,
|
97
|
-
go(2 +
|
98
|
-
go(1
|
113
|
+
go(2 + @work, @len + 3) + "└" + "─" * (@wide + 2) + "┘\n",
|
114
|
+
go(1 , @len + 3) + "┌" + "─" * (@wide + 2) + "┐\n",
|
99
115
|
].join
|
100
|
-
|
116
|
+
@work.times {|i| print " %*d │ %*s │\n" % [@len, i + 1, @wide, ""] }
|
101
117
|
return
|
102
118
|
end
|
103
119
|
|
104
120
|
# worker bars
|
105
|
-
dpct = done.to_f / jobs
|
106
121
|
lpct = live.to_f / jobs
|
122
|
+
dpct = done.to_f / jobs
|
107
123
|
most = info.values.max
|
108
124
|
info.each do |slot, this|
|
109
125
|
tpct = this.to_f / most
|
@@ -115,12 +131,12 @@ def draw(rows, done=0, live=0, bomb=0, jobs=0, info=nil)
|
|
115
131
|
gcol = dpct * @wide
|
116
132
|
ycol = lpct * @wide
|
117
133
|
print [
|
118
|
-
go(
|
134
|
+
go(@work + 3, @len + 5),
|
119
135
|
fg("fff"),
|
120
136
|
bg("58a65c") + @char * ( gcol ) , # green (done)
|
121
|
-
bg("f1bf42") + @char * ( ycol) , # yellow (live)
|
137
|
+
bg("f1bf42") + @char * ( ycol) , # yellow (live)
|
122
138
|
bg("d85140") + " " * (@wide - gcol - ycol).ceil, # red (left)
|
123
|
-
go(
|
139
|
+
go(@work + 3, @len + 5 + @wide + 3) + " %.1f%% done " % [dpct * 100],
|
124
140
|
bomb == 0 ? nil : (bg + " " + bg("f1bf42") + " #{bomb} bombed "),
|
125
141
|
].join
|
126
142
|
|
@@ -136,7 +152,7 @@ FileUtils.mkdir_p @live
|
|
136
152
|
FileUtils.mkdir_p @done
|
137
153
|
FileUtils.mkdir_p @bomb
|
138
154
|
|
139
|
-
|
155
|
+
100.times {|i| FileUtils.touch(File.join(@todo, (i + 1).to_s)) }
|
140
156
|
|
141
157
|
# ==[ Configure workers ]=====================================================
|
142
158
|
|
@@ -149,43 +165,46 @@ begin
|
|
149
165
|
jobs = list.size
|
150
166
|
info = Hash.new(0)
|
151
167
|
|
152
|
-
setup
|
168
|
+
setup if defined?(setup)
|
153
169
|
|
154
170
|
cursor(false)
|
155
|
-
draw
|
156
|
-
|
157
|
-
time = Time.now
|
158
|
-
done = 0
|
171
|
+
draw
|
159
172
|
live = 0
|
173
|
+
done = 0
|
160
174
|
bomb = 0
|
175
|
+
time = Time.now
|
161
176
|
Thread.new do
|
162
|
-
list.
|
177
|
+
list.each_with_index do |path, task|
|
163
178
|
slot = @que.pop
|
164
179
|
@mtx.synchronize {
|
165
180
|
live += 1
|
166
181
|
}
|
167
182
|
show = "Working on task " + File.basename(path)
|
168
|
-
print go(slot + 1, @len + 5 + @wide + 3) + show
|
183
|
+
print go(slot + 1, @len + 5 + @wide + 3) + show + clear(true)
|
169
184
|
if chld = fork # parent
|
170
185
|
Thread.new do
|
171
186
|
okay = Process.waitpid2(chld)[1] == 0
|
172
187
|
move(path, okay ? @done : @bomb)
|
173
188
|
@que.push(slot)
|
174
189
|
@mtx.synchronize {
|
175
|
-
done += 1
|
176
190
|
live -= 1
|
191
|
+
done += 1
|
177
192
|
bomb += 1 unless okay
|
178
193
|
info[slot] += 1
|
179
194
|
}
|
180
195
|
end
|
181
|
-
draw(
|
196
|
+
draw(live, done, bomb, jobs, info.dup)
|
182
197
|
else
|
198
|
+
case @wait
|
199
|
+
when "rand" then sleep rand(@work)
|
200
|
+
when "task" then sleep task
|
201
|
+
when Numeric then sleep task * @wait
|
202
|
+
end if task < @work
|
183
203
|
perform(slot, path)
|
184
204
|
exit
|
185
205
|
end
|
186
206
|
end
|
187
207
|
end.join
|
188
|
-
draw(@work, done, live, bomb, jobs, info)
|
189
208
|
secs = Time.now.to_f - time.to_f
|
190
209
|
|
191
210
|
# summary
|