Skip to content

Commit d2fdc22

Browse files
committed
fix: progress bars update too frequently
1 parent 776a111 commit d2fdc22

File tree

1 file changed

+26
-10
lines changed

1 file changed

+26
-10
lines changed

src/install.zig

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ const CommonPaths = paths.CommonPaths;
1212
const http = std.http;
1313
const Sha256 = std.crypto.hash.sha2.Sha256;
1414
const release_name = common.release_name;
15+
const AtomicOrder = std.builtin.AtomicOrder;
16+
const time = std.time;
1517

1618
const default_os = builtin.target.os.tag;
1719
const default_arch = builtin.target.cpu.arch;
@@ -115,35 +117,49 @@ pub fn download_tarball(alloc: Allocator, client: *Client, tb_url: []const u8, t
115117
try req.?.wait();
116118
var reader = req.?.reader();
117119

118-
var progress_bar: [150]u8 = ("░" ** 50).*;
119-
var stderr_writer = std.io.getStdErr().writer();
120120
var buff: [1024]u8 = undefined;
121-
var bars: u8 = 0;
122121

123122
// Convert everything into f64 for less typing in calculating % download and download speed
124-
var dlnow: f64 = @floatFromInt(tarball_size);
123+
var dlnow = std.atomic.Value(f64).init(0);
125124
const total_size_double: f64 = @floatFromInt(total_size);
126125

126+
const progress_thread = try std.Thread.spawn(.{}, download_progress_bar, .{ &dlnow, @as(f64, @floatFromInt(tarball_size)), total_size_double });
127127
while (true) {
128128
const len = try reader.read(&buff);
129129
if (len == 0) {
130130
break;
131131
}
132132
_ = try tb_writer.write(buff[0..len]);
133133

134-
dlnow += @floatFromInt(len);
135-
const pcnt_complete: u8 = @intFromFloat(dlnow * 100 / total_size_double);
136-
var timer = try std.time.Timer.start();
134+
_ = dlnow.fetchAdd(@floatFromInt(len), AtomicOrder.monotonic);
135+
}
136+
progress_thread.join();
137+
try tb_writer.flush();
138+
}
139+
140+
pub fn download_progress_bar(dlnow: *std.atomic.Value(f64), tarball_size: f64, total_size: f64) !void {
141+
var stderr_writer = std.io.getStdErr().writer();
142+
var progress_bar: [150]u8 = ("░" ** 50).*;
143+
var bars: u8 = 0;
144+
var timer = try time.Timer.start();
145+
var downloaded = dlnow.load(AtomicOrder.monotonic);
146+
147+
while (true) {
148+
const pcnt_complete: u8 = @intFromFloat((downloaded + tarball_size) * 100 / total_size);
137149
const newbars: u8 = pcnt_complete / 2;
138150
for (bars..newbars) |i| {
139151
std.mem.copyForwards(u8, progress_bar[i * 3 .. i * 3 + 3], "█");
140152
}
141153
bars = newbars;
142-
const dlspeed = dlnow / 1024 * 8 / @as(f64, @floatFromInt(timer.read()));
143-
try stderr_writer.print("\r\t\x1b[33m{s}\x1b[0m{s} {d}% {d:.1}kb/s", .{ progress_bar[0 .. newbars * 3], progress_bar[newbars * 3 ..], pcnt_complete, dlspeed });
154+
const speed = downloaded / 1024 / @as(f64, @floatFromInt(timer.read() / time.ns_per_s));
155+
try stderr_writer.print("\r\t\x1b[33m{s}\x1b[0m{s} {d}% {d:.1}KB/s", .{ progress_bar[0 .. newbars * 3], progress_bar[newbars * 3 ..], pcnt_complete, speed });
156+
157+
if (downloaded + tarball_size == total_size) break;
158+
159+
std.time.sleep(500 * time.ns_per_ms);
160+
downloaded = dlnow.load(AtomicOrder.monotonic);
144161
}
145162
try stderr_writer.print("\n", .{});
146-
try tb_writer.flush();
147163
}
148164

149165
pub fn get_json_dslist(client: *Client) anyerror!JsonResponse {

0 commit comments

Comments
 (0)