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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/vete.rb +46 -27
  3. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1d1ef6e5614f544a633cfe36109f37ef7a37676b7ba276be48abcc40d6e9cf54
4
- data.tar.gz: a0036c27a47eddba9385673345f4456fbae869fa816c8c2c0d46ce92a0866d82
3
+ metadata.gz: 31328c3602f1174d697b56c9d0b8049986b68151975ed05c2febe3bab04d0c00
4
+ data.tar.gz: e4d99dd8303a7bcc8d589f66bb6ad0a0e2b79bfb718c7f2856f2e3a7aa558e63
5
5
  SHA512:
6
- metadata.gz: a0f287195bba7b81a368560aa3f0694b60e7afe8292957b9d947ca820291b603bdfc3d231bd9432c175a4f3df88714eba91b7a41db5dea744154e063000d2e42
7
- data.tar.gz: 0aeb6cfa54c5a55d6b822ce29e5045f78176b428bd2948fd039ea5dce5096d42a0d7dd6e8b04ce2c2631fb28bd02480f79e5c75fdb8a489e729f614ae191c428
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
- trap("INT" ) { print clear + go; abort "\n" }
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.2.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 "-r", "--reset" , "Remove directory used for job processing and quit"
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 ; "\e[2J" ; end
80
- def cursor(on) ; print on ? "\e[?25h": "\e[?25l"; end
81
- def go(r=1,c=1); "\e[#{r};#{c}H" ; end
82
- def go!(...) ; print go(...) ; end
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(rows, done=0, live=0, bomb=0, jobs=0, info=nil)
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 + rows, @len + 3) + "└" + "─" * (@wide + 2) + "┘\n",
98
- go(1 , @len + 3) + "┌" + "─" * (@wide + 2) + "┐\n",
113
+ go(2 + @work, @len + 3) + "└" + "─" * (@wide + 2) + "┘\n",
114
+ go(1 , @len + 3) + "┌" + "─" * (@wide + 2) + "┐\n",
99
115
  ].join
100
- rows.times {|i| print " %*d │ %*s │\n" % [@len, i + 1, @wide, ""] }
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(rows + 3, @len + 5),
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) <= Add live
137
+ bg("f1bf42") + @char * ( ycol) , # yellow (live)
122
138
  bg("d85140") + " " * (@wide - gcol - ycol).ceil, # red (left)
123
- go(rows + 3, @len + 5 + @wide + 3) + " %.1f%% done " % [dpct * 100],
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
- 1.upto(100) {|i| FileUtils.touch(File.join(@todo, i.to_s)) }
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(@work)
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.each do |path|
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(@work, done, live, bomb, jobs, info.dup)
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
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.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Shreeve