Skip to content

Instantly share code, notes, and snippets.

@andrewrk
Last active May 24, 2024 04:19
Show Gist options
  • Save andrewrk/b22b4f663cef6b4672d7097de95ea343 to your computer and use it in GitHub Desktop.
Save andrewrk/b22b4f663cef6b4672d7097de95ea343 to your computer and use it in GitHub Desktop.
progress API test case
https://asciinema.org/a/gDna9RnicwYjDRIDn4e07NFSc
const std = @import("std");
pub fn main() !void {
const gpa = std.heap.page_allocator;
var draw_buffer: [1000]u8 = undefined;
const root_node = std.Progress.start(.{
.draw_buffer = &draw_buffer,
.root_name = "grandparent work",
});
defer root_node.end();
const another_node = root_node.start("gardening", 25);
const child_node = root_node.start("have children", 0);
defer child_node.end();
var child = std.process.Child.init(&.{"./prog-parent"}, gpa);
child.progress_node = child_node;
try child.spawn();
{
defer another_node.end();
for (0..25) |_| {
std.time.sleep(130 * std.time.ns_per_ms);
another_node.completeOne();
}
}
const term = try child.wait();
_ = term;
}
const std = @import("std");
pub fn main() !void {
const gpa = std.heap.page_allocator;
var draw_buffer: [1000]u8 = undefined;
const root_node = std.Progress.start(.{
.draw_buffer = &draw_buffer,
.root_name = "accomplishing things",
});
defer root_node.end();
const child_node = root_node.start("child process node", 0);
defer child_node.end();
var child = std.process.Child.init(&.{"./prog"}, gpa);
child.progress_node = child_node;
try child.spawn();
{
const another_node = root_node.start("parent process work", 20);
defer another_node.end();
for (0..20) |_| {
std.time.sleep(175 * std.time.ns_per_ms);
another_node.completeOne();
}
}
const term = try child.wait();
_ = term;
}
const std = @import("std");
pub fn main() !void {
var draw_buffer: [1000]u8 = undefined;
const root_node = std.Progress.start(.{
.draw_buffer = &draw_buffer,
.estimated_total_items = 100,
.root_name = "crunching some numbers",
});
defer root_node.end();
const fake_worker = try std.Thread.spawn(.{}, fakeWork, .{ root_node, "thread worker" });
defer fake_worker.join();
const slow_worker = try std.Thread.spawn(.{}, slowWork, .{root_node});
defer slow_worker.join();
const speed_factor = std.time.ns_per_ms;
const sub_task_names = [_][]const u8{
"reticulating splines",
"adjusting shoes",
"climbing towers",
"pouring juice",
};
var next_sub_task: usize = 0;
var i: usize = 0;
while (i < 100) : (i += 1) {
const node = root_node.start(sub_task_names[next_sub_task], 5);
next_sub_task = (next_sub_task + 1) % sub_task_names.len;
node.completeOne();
std.time.sleep(5 * speed_factor);
node.completeOne();
node.completeOne();
std.time.sleep(5 * speed_factor);
node.completeOne();
node.completeOne();
std.time.sleep(5 * speed_factor);
node.end();
std.time.sleep(5 * speed_factor);
}
{
var node = root_node.start("this is a really long name designed to activate the truncation code. let's find out if it works", 0);
std.time.sleep(10 * speed_factor);
std.time.sleep(10 * speed_factor);
node.end();
}
}
fn fakeWork(parent_node: std.Progress.Node, name: []const u8) void {
const node = parent_node.start(name, 10);
defer node.end();
for (0..10) |_| {
std.time.sleep(50 * std.time.ns_per_ms);
node.completeOne();
}
}
const lorem_names = [_][]const u8{ "Lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing", "elit", "sed", "do", "eiusmod", "tempor", "incididunt", "ut", "labore", "et", "dolore", "magna", "aliqua" };
fn slowWork(parent_node: std.Progress.Node) !void {
const node = parent_node.start("slow task", lorem_names.len);
defer node.end();
for (lorem_names) |name| {
const sub = node.start(name, 0);
defer sub.end();
const fake_worker = try std.Thread.spawn(.{}, fakeWork, .{ sub, "count to ten" });
defer fake_worker.join();
}
}
@mikdusan
Copy link

if peek is real important it seems poll/select can do it:

const std = @import("std");
const posix = std.posix;

// peek fifo file every second and read data when available
// usage: peek <FIFO_FILENAME>
//
// example:
//  window 1
//      mkfifo /tmp/fifo
//      main /tmp/fifo
//  window 2
//      cat > /tmp/fifo
//      hello
//      world
//      <CTRL-D>
//
pub fn main() !void {
    var arena_obj = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    defer arena_obj.deinit();
    const arena = arena_obj.allocator();
    const args = try std.process.argsAlloc(arena);

    // fd must be .NONBLOCK
    const fd = try posix.open(args[1], .{ .NONBLOCK = true }, 0);
    defer posix.close(fd);

    while (true) {
        std.time.sleep(1 * std.time.ns_per_s);
        const ready = try peek(fd);
        std.log.debug("peek: {}", .{ready});
        if (!ready) continue;

        var buf: [128]u8 = undefined;
        const nr = try posix.read(fd, &buf);
        std.log.debug("data: {s}", .{buf[0..nr]});
    }
}

fn peek(fd: posix.fd_t) !bool {
    var fds: [1]posix.pollfd = .{
        .{
            .fd = fd,
            .events = posix.POLL.IN | posix.POLL.HUP,
            .revents = undefined,
        },
    };
    const rv = try posix.poll(&fds, 0);
//  std.log.debug("poll rv={} revents=0x{x}", .{rv, fds[0].revents});
    if (rv == 0) return false;
    if (fds[0].revents & posix.POLL.IN != 0) return true;
    if (fds[0].revents & posix.POLL.HUP != 0) return error.HUP;
    return error.Unknown;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment