vete 0.2.0 → 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/lib/vete.rb +64 -49
- data/test/example.rb +4 -2
- data/test/vete.gif +0 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9e19484c6c02cd403365def0a14367e2c31f302edd7b56842e863162d0178730
|
4
|
+
data.tar.gz: 303793b8c478fe08733f2da221a325d66e68b2d3ab54c89105482ef612866953
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 59e65ecb548ffa4ccc95f4928f83cb036cefaae98e447801c03616627557614f871f24442b331fd1f6d1211beaf8559f7b98870ea3e31a316ab22af6041d438f
|
7
|
+
data.tar.gz: 03aef3e49b3ee52dbd6867adee656d67fb6124f3eabc027732d35be04e46b0db0139a59abfc00d64079d2f4ce95b6d2cb24cb7e1f752283168196f965e028adb
|
data/lib/vete.rb
CHANGED
@@ -13,16 +13,20 @@ require "fileutils"
|
|
13
13
|
require "optparse"
|
14
14
|
require "thread"
|
15
15
|
|
16
|
-
|
16
|
+
@pid = Process.pid
|
17
|
+
|
18
|
+
trap("INT" ) { print clear + go; abort "\n" }
|
19
|
+
trap("WINCH") { print clear or draw if @pid == Process.pid }
|
17
20
|
|
18
21
|
OptionParser.new.instance_eval do
|
19
|
-
@version = "0.
|
22
|
+
@version = "0.6.0"
|
20
23
|
@banner = "usage: #{program_name} [options]"
|
21
24
|
|
22
25
|
on "-b", "--bar <width>" , "Progress bar width, in characters", Integer
|
23
26
|
on "-c", "--char <character>" , "Character to use for progress bar", String
|
24
|
-
on "-
|
27
|
+
on "-d", "--delay <mode>" , "Delay mode (rand, task, numeric)"
|
25
28
|
on "-h", "--help" , "Show help and command usage" do Kernel.abort to_s; end
|
29
|
+
on "-r", "--reset" , "Remove directory used for job processing and quit"
|
26
30
|
on "-v", "--version" , "Show version number" do Kernel.abort "#{program_name} #{@version}"; end
|
27
31
|
on "-w", "--workers <count>" , "Set the number of workers (default is 1)", Integer
|
28
32
|
|
@@ -31,17 +35,27 @@ end.parse!(into: opts={}) rescue abort($!.message)
|
|
31
35
|
|
32
36
|
# populate CLI options
|
33
37
|
@char = opts[:char ] || "•"; @char = @char[0]
|
38
|
+
@wait = opts[:delay ]
|
34
39
|
@nuke = opts[:reset ]
|
35
40
|
@wide = opts[:bar ] || 20
|
36
41
|
@work = opts[:workers] || 1
|
37
42
|
|
43
|
+
# handle wait mode
|
44
|
+
case @wait
|
45
|
+
when "rand", "task", nil
|
46
|
+
when /\A(?:0|[1-9]\d*|(?:0?\.|[1-9]\d*\.)\d*)\z/
|
47
|
+
@wait = @wait.to_f
|
48
|
+
@wait > 0 or abort "invalid delay time (#{@wait.to_f} secs)"
|
49
|
+
else
|
50
|
+
abort "invalid delay mode '#{@wait}'"
|
51
|
+
end
|
52
|
+
|
38
53
|
# define job directories
|
39
54
|
@vete = File.expand_path(".vete")
|
40
55
|
@todo = File.join(@vete, "todo")
|
41
56
|
@live = File.join(@vete, "live")
|
42
57
|
@done = File.join(@vete, "done")
|
43
|
-
@
|
44
|
-
|
58
|
+
@died = File.join(@vete, "died")
|
45
59
|
|
46
60
|
def move(path, dest)
|
47
61
|
dest = File.join(dest, File.basename(path))
|
@@ -59,27 +73,27 @@ end
|
|
59
73
|
|
60
74
|
def vete_init
|
61
75
|
nuke
|
62
|
-
list = [@todo, @live, @done, @
|
63
|
-
list.each {|path|
|
76
|
+
list = [@todo, @live, @done, @died]
|
77
|
+
list.each {|path| FileUtils.mkdir_p(path) }
|
64
78
|
end
|
65
79
|
|
66
80
|
def vete_retry
|
67
|
-
list = Dir.glob(File.join(@
|
81
|
+
list = Dir.glob(File.join(@died, "*")).sort.each {|path| FileUtils.touch(path) }
|
68
82
|
move(list, @todo)
|
69
83
|
end
|
70
84
|
|
71
85
|
def vete_todo(path)
|
72
|
-
FileUtils.touch(
|
86
|
+
FileUtils.touch(File.join(@todo, path.to_s))
|
73
87
|
end
|
74
88
|
|
75
89
|
# ==[ Drawing ]===============================================================
|
76
90
|
|
77
91
|
# https://www.cse.psu.edu/~kxc104/class/cmpen472/16f/hw/hw8/vt100ansi.htm
|
78
92
|
|
79
|
-
def clear
|
80
|
-
def cursor(on)
|
81
|
-
def go(r=1,c=1); "\e[#{r};#{c}H" ; end
|
82
|
-
def go!(...)
|
93
|
+
def clear(line=nil); line ? "\e[K" : "\e[2J" ; end
|
94
|
+
def cursor(on) ; print on ? "\e[?25h": "\e[?25l"; end
|
95
|
+
def go(r=1,c=1) ; "\e[#{r};#{c}H" ; end
|
96
|
+
def go!(...) ; print go(...) ; end
|
83
97
|
|
84
98
|
def fg(rgb=nil); rgb ? "\e[38;2;#{hx(rgb)}m" : "\e[39m"; end
|
85
99
|
def bg(rgb=nil); rgb ? "\e[48;2;#{hx(rgb)}m" : "\e[49m"; end
|
@@ -88,56 +102,49 @@ def hx(str=nil); str =~ /\A#?(?:(\h\h)(\h\h)(\h\h)|(\h)(\h)(\h))\z/ or return
|
|
88
102
|
[r.hex, g.hex, b.hex] * ";"
|
89
103
|
end
|
90
104
|
|
91
|
-
def draw(
|
105
|
+
def draw(live=0, done=0, died=0, jobs=0, info=nil)
|
92
106
|
|
93
107
|
# outer box
|
94
108
|
unless info
|
95
109
|
print [
|
96
110
|
clear,
|
97
|
-
go(2 +
|
98
|
-
go(1
|
111
|
+
go(2 + @work, @len + 3) + "└" + "─" * (@wide + 2) + "┘\n",
|
112
|
+
go(1 , @len + 3) + "┌" + "─" * (@wide + 2) + "┐\n",
|
99
113
|
].join
|
100
|
-
|
114
|
+
@work.times {|i| print " %*d │ %*s │\n" % [@len, i + 1, @wide, ""] }
|
101
115
|
return
|
102
116
|
end
|
103
117
|
|
104
118
|
# worker bars
|
105
|
-
|
106
|
-
lpct = live.to_f / jobs
|
119
|
+
ppct = (done + died).to_f / jobs
|
107
120
|
most = info.values.max
|
108
121
|
info.each do |slot, this|
|
109
122
|
tpct = this.to_f / most
|
110
|
-
cols =
|
123
|
+
cols = ppct * tpct * @wide
|
111
124
|
print go(slot + 1, @len + 5) + bg("5383ec") + @char * cols
|
112
125
|
end
|
113
126
|
|
114
127
|
# summary bar
|
128
|
+
dpct = done.to_f / jobs
|
129
|
+
lpct = live.to_f / jobs
|
115
130
|
gcol = dpct * @wide
|
116
131
|
ycol = lpct * @wide
|
117
132
|
print [
|
118
|
-
go(
|
133
|
+
go(@work + 3, @len + 5),
|
119
134
|
fg("fff"),
|
120
135
|
bg("58a65c") + @char * ( gcol ) , # green (done)
|
121
|
-
bg("f1bf42") + @char * ( ycol) , # yellow (live)
|
122
|
-
bg("d85140") + " " * (@wide - gcol - ycol).ceil, # red (
|
123
|
-
go(
|
124
|
-
|
136
|
+
bg("f1bf42") + @char * ( ycol) , # yellow (live)
|
137
|
+
bg("d85140") + " " * (@wide - gcol - ycol).ceil, # red (rest)
|
138
|
+
go(@work + 3, @len + 5 + @wide + 3) , # scoot over...
|
139
|
+
bg("5383ec") + " %.1f%% " % [ppct * 100], # blue (done + died)
|
140
|
+
done > 0 ? (bg + " " + bg("58a65c") + " #{done} done ") : nil,
|
141
|
+
died > 0 ? (bg + " " + bg("d85140") + " #{died} died ") : nil,
|
125
142
|
].join
|
126
143
|
|
127
144
|
# clear colors
|
128
145
|
print fg + bg
|
129
146
|
end
|
130
147
|
|
131
|
-
# ==[ Simulate job creation, add helpers so vete makes this easy ]============
|
132
|
-
|
133
|
-
FileUtils.rm_rf @vete
|
134
|
-
FileUtils.mkdir_p @todo
|
135
|
-
FileUtils.mkdir_p @live
|
136
|
-
FileUtils.mkdir_p @done
|
137
|
-
FileUtils.mkdir_p @bomb
|
138
|
-
|
139
|
-
1.upto(100) {|i| FileUtils.touch(File.join(@todo, i.to_s)) }
|
140
|
-
|
141
148
|
# ==[ Configure workers ]=====================================================
|
142
149
|
|
143
150
|
@len = @work.to_s.size
|
@@ -145,47 +152,55 @@ FileUtils.mkdir_p @bomb
|
|
145
152
|
@que = Thread::Queue.new; @work.times {|slot| @que << (slot + 1) }
|
146
153
|
|
147
154
|
begin
|
155
|
+
setup if defined?(setup)
|
156
|
+
|
148
157
|
list = Dir[File.join(@todo, "*")]
|
158
|
+
|
159
|
+
live = 0
|
160
|
+
done = 0
|
161
|
+
died = 0
|
149
162
|
jobs = list.size
|
150
163
|
info = Hash.new(0)
|
151
164
|
|
152
|
-
setup
|
153
|
-
|
154
165
|
cursor(false)
|
155
|
-
draw
|
166
|
+
draw
|
156
167
|
|
157
168
|
time = Time.now
|
158
|
-
done = 0
|
159
|
-
live = 0
|
160
|
-
bomb = 0
|
161
169
|
Thread.new do
|
162
|
-
list.
|
170
|
+
list.each_with_index do |path, task|
|
163
171
|
slot = @que.pop
|
164
172
|
@mtx.synchronize {
|
165
173
|
live += 1
|
166
174
|
}
|
167
175
|
show = "Working on task " + File.basename(path)
|
168
|
-
print go(slot + 1, @len + 5 + @wide + 3) + show
|
176
|
+
print go(slot + 1, @len + 5 + @wide + 3) + show + clear(true)
|
169
177
|
if chld = fork # parent
|
170
178
|
Thread.new do
|
171
179
|
okay = Process.waitpid2(chld)[1] == 0
|
172
|
-
move(path, okay ? @done : @
|
180
|
+
move(path, okay ? @done : @died)
|
173
181
|
@que.push(slot)
|
174
182
|
@mtx.synchronize {
|
175
|
-
done += 1
|
176
183
|
live -= 1
|
177
|
-
|
184
|
+
okay ? (done += 1) : (died += 1)
|
178
185
|
info[slot] += 1
|
179
186
|
}
|
180
187
|
end
|
181
|
-
draw(
|
188
|
+
draw(live, done, died, jobs, info.dup)
|
182
189
|
else
|
183
|
-
|
190
|
+
case @wait
|
191
|
+
when "rand" then sleep rand(@work)
|
192
|
+
when "task" then sleep task
|
193
|
+
when Numeric then sleep task * @wait
|
194
|
+
end if task < @work
|
195
|
+
perform(path)
|
184
196
|
exit
|
185
197
|
end
|
186
198
|
end
|
199
|
+
while @que.size != @work
|
200
|
+
sleep 1
|
201
|
+
draw(live, done, died, jobs, info.dup)
|
202
|
+
end
|
187
203
|
end.join
|
188
|
-
draw(@work, done, live, bomb, jobs, info)
|
189
204
|
secs = Time.now.to_f - time.to_f
|
190
205
|
|
191
206
|
# summary
|
data/test/example.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
def setup
|
4
|
+
vete_init
|
5
|
+
100.times {|i| vete_todo(i + 1) }
|
4
6
|
@time = Time.now
|
5
7
|
end
|
6
8
|
|
7
|
-
def perform(
|
9
|
+
def perform(task)
|
8
10
|
sleep rand
|
9
11
|
secs = Time.now - @time
|
10
|
-
exit
|
12
|
+
exit 1 if rand < 0.03
|
11
13
|
end
|
12
14
|
|
13
15
|
require_relative "../lib/vete"
|
data/test/vete.gif
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vete
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steve Shreeve
|
@@ -42,7 +42,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
42
42
|
- !ruby/object:Gem::Version
|
43
43
|
version: '0'
|
44
44
|
requirements: []
|
45
|
-
rubygems_version: 3.4.
|
45
|
+
rubygems_version: 3.4.9
|
46
46
|
signing_key:
|
47
47
|
specification_version: 4
|
48
48
|
summary: Ruby CLI to spawn processes to get work done
|