### Build Examples Command Source: https://github.com/lalinsky/zio/blob/main/README.md Command to build all examples included in the Zio project. Ensure you have Zig installed and the project cloned. ```bash zig build examples ``` -------------------------------- ### Full HTTP Server Example Source: https://github.com/lalinsky/zio/blob/main/docs/http-server.md A complete Zig program demonstrating an HTTP server using ZIO. This example sets up the server, handles incoming connections, and responds to HTTP requests, showcasing ZIO's compatibility with standard Zig I/O interfaces. ```zig const std = @import("std"); const zio = @import("zio"); pi: std.mem.Allocator, pi = try std.heap.GeneralPurposeAllocator(.{}) .init(.{}); defer _ = pi.destroy(); const server = try std.http.Server.init(pi, client_stream); defer server.deinit(); while (server.handleRequest()) |request| { const response = try request.respond(.{ .status = .ok, .body = "Hello from ZIO!\n" }); if (!response.keep_alive) { break; } } ``` -------------------------------- ### Basic TCP Echo Server Example Source: https://github.com/lalinsky/zio/blob/main/docs/index.md A simple TCP echo server implementation using ZIO. This example demonstrates basic network I/O and ZIO's coroutine capabilities. ```zig const std = @import("std"); const zio = @import("zio"); pi(std.log.debug("Server started on {s}", .{\"0.0.0.0:8080\"})); while (true) { const client = try server.accept(); zio.spawn(handle_client(client)); } fn handle_client(client: zio.net.TcpStream) !void { defer client.close(); var buffer: [1024]u8 = undefined; while (try client.read(&buffer)) |bytes_read| { try client.writeAll(&buffer[0..bytes_read]); } } export fn main() !void { var server = try zio.net.TcpListener.listen("0.0.0.0:8080"); defer server.close(); try std.Thread.detach(handle_connections(server)); // Keep the main thread alive std.Thread.sleep(1000000000); } fn handle_connections(server: zio.net.TcpListener) !void { while (true) { const client = try server.accept(); zio.spawn(handle_client(client)); } } ``` -------------------------------- ### Setup TCP Listener Source: https://github.com/lalinsky/zio/blob/main/docs/tcp-server.md Initializes the runtime and creates a TCP listener on a specified address and port. This is the first step in setting up a network server. ```zig const std = @import("std"); const z = @import("zhttp"); const Allocator = std.mem.Allocator; const Net = std.net; const TcpListener = Net.TcpListener; pi: pub fn main(allocator: Allocator) !void { var runtime = try z.runtime.init(allocator); defer runtime.deinit(); const listener = try TcpListener.listen(.{.host = "127.0.0.1", .port = 8080}); std.log.info("TCP echo server listening on {}:{}", @as([_][]const u8, &.{ listener.host.?, listener.port.? }) \ ); std.log.info("Press Ctrl+C to stop the server", .{}); // ... rest of the code } ``` -------------------------------- ### DNS Lookup Example Source: https://github.com/lalinsky/zio/blob/main/docs/ntp-client.md Resolves a hostname to an IP address asynchronously. Handles multiple potential IP addresses. ```zig const address = try net.resolveAddress(server_host, server_port); ``` -------------------------------- ### Initialize and Run Event Loop with Timer Source: https://github.com/lalinsky/zio/blob/main/src/ev/README.md This example demonstrates how to initialize the zio.ev event loop, add a timer that fires after a specified duration, and handle the timer callback. The timer is re-armed within the callback to make it reschedule. ```zig const std = @import("std"); const ev = @import("zio").ev; pub fn main() !void { var gpa: std.heap.GeneralPurposeAllocator(.{}) = .{}; defer _ = gpa.deinit(); var loop: ev.Loop = undefined; try loop.init(.{ .allocator = gpa.allocator() }); defer loop.deinit(); var timer: ev.Timer = .init(.{ .duration = .fromSeconds(1) }); timer.c.callback = timerCallback; loop.add(&timer.c); try loop.run(.until_done); } fn timerCallback(loop: *ev.Loop, c: *ev.Completion) void { const timer: *ev.Timer = c.cast(ev.Timer); timer.getResult() catch |err| { std.debug.print("timer error: %\n", .{err}); return; }; std.debug.print("timer fired!\n", .{}); loop.add(c); // re-arm the timer } ``` -------------------------------- ### NTP Client Main Code Source: https://github.com/lalinsky/zio/blob/main/docs/ntp-client.md The main ZIO application code for the NTP client. Requires Zig and ZIO setup. ```zig const std = @import("std"); const NtpPacket = extern struct { flags: packed struct(u8) { mode: u3 = 3, // Client mode version: u3 = 3, // NTP version 3 leap: u2 = 0, // No leap second warning } = .{}, stratum: u8 = 0, poll: u8 = 0, precision: u8 = 0, root_delay: u32 = 0, root_dispersion: u32 = 0, reference_id: u32 = 0, reference_timestamp: u64 = 0, origin_timestamp: u64 = 0, receive_timestamp: u64 = 0, transmit_timestamp: u64 = 0, }; pi @import("zio").main { const log = std.log; const net = @import("zio.net"); const time = @import("zio.time"); const server_host = "pool.ntp.org"; const server_port: u16 = 123; const update_interval = time.Duration.fromSeconds(30); const request_timeout = time.Duration.fromSeconds(5); log.info("NTP client starting. Press Ctrl+C to stop."); log.info("Server: {s}:{d}", .{ server_host, server_port, }); log.info("Update interval: {d}", .{ update_interval, }); log.info("Request timeout: {d}", .{ request_timeout, }); const address = try net.resolveAddress(server_host, server_port); log.info("Querying NTP server {s}:{d} ({any}:{d})", .{ server_host, server_port, address, server_port, }); const socket = try net.UdpSocket.bind(.anyAddress, 0)?; defer socket.close(); var buffer: [1024]u8 = undefined; while (true) { const request: NtpPacket = .{}; var writer = std.io.Writer.fixed(&buffer[0..@sizeOf(NtpPacket)]); try writer.writeStruct(request, .big); try socket.sendTo(&buffer[0..@sizeOf(NtpPacket)], address); const result = socket.receiveFrom(&buffer, request_timeout) catch |err| switch (err) { error.Timeout => { log.warn("Request timed out.", .{}); continue; }, else => return err, }; var reader = std.io.Reader.fixed(result.data[0..result.len]); const response = try reader.takeStruct(NtpPacket, .big); const transmit_timestamp_ntp = response.transmit_timestamp; const transmit_timestamp_unix = transmit_timestamp_ntp - NtpPacket.reference_timestamp; const current_time = time.Instant.fromEpochSeconds(transmit_timestamp_unix); log.info("Current time: {any}", .{ current_time.format(time.DateTimeFormat.iso), }); time.sleep(update_interval); } } ``` -------------------------------- ### Parallel Grep Main Execution Source: https://github.com/lalinsky/zio/blob/main/docs/parallel-grep.md The main ZIG code for the parallel grep tool, including runtime initialization, channel setup, worker spawning, and coordination. ```zig --8<-- "examples/parallel_grep.zig" ``` -------------------------------- ### Hello World Program Source: https://github.com/lalinsky/zio/blob/main/docs/getting-started.md A basic 'Hello, world!' program using ZIO. It demonstrates runtime initialization, stdout access, and writing to the console. The `writeAll()` call submits an asynchronous write operation. ```zig --8<-- "examples/hello_world.zig" ``` -------------------------------- ### Run Hello World Application Source: https://github.com/lalinsky/zio/blob/main/docs/getting-started.md Builds and runs the Zig application. This command executes the 'Hello, world!' program. ```sh $ zig build run Hello, world! ``` -------------------------------- ### Initialize New Zig Project Source: https://github.com/lalinsky/zio/blob/main/docs/getting-started.md Initializes a new Zig project with default build files and source structure. ```sh $ zig init info: created build.zig info: created build.zig.zon info: created src/main.zig info: created src/root.zig info: see `zig build --help` for a menu of options ``` -------------------------------- ### Accept Connections and Spawn Tasks Source: https://github.com/lalinsky/zio/blob/main/docs/tcp-server.md Enters a loop to accept incoming TCP connections. For each connection, a new task is spawned to handle the client concurrently using the task group. ```zig while (true) { const stream = listener.accept() catch |err| { std.log.err("Failed to accept connection: {s}", .{@errorName(err)}); continue; }; errdefer stream.close(); try group.spawn(handleClient(runtime.allocator, stream)); } ``` -------------------------------- ### Build and Run Server Source: https://github.com/lalinsky/zio/blob/main/docs/tcp-server.md Command to build the Zig project and run the TCP echo server. Assumes the project is set up with a build.zig file. ```sh zig build run ``` -------------------------------- ### Initialize HTTP Server Source: https://github.com/lalinsky/zio/blob/main/docs/http-server.md Initializes an HTTP server instance for each client connection. It leverages Zig's standard `std.http.Server` which works with any `std.Io.Reader` and `std.Io.Writer` interfaces. ```zig const server = try std.http.Server.init(allocator, client_stream); defer server.deinit(); ``` -------------------------------- ### Import ZIO Module in build.zig Source: https://github.com/lalinsky/zio/blob/main/README.md Add the ZIO module as a dependency to your program in your build.zig file. ```zig const zio = b.dependency("zio", .{ .target = target, .optimize = optimize, }); exe.root_module.addImport("zio", zio.module("zio")); ``` -------------------------------- ### Configure Build for ZIO Source: https://github.com/lalinsky/zio/blob/main/docs/getting-started.md Integrates the ZIO dependency into your Zig project's build configuration. ```zig const zio = b.dependency("zio", .{ .target = target, .optimize = optimize, }); exe.root_module.addImport("zio", zio.module("zio")); ``` -------------------------------- ### Handle Client Connection Source: https://github.com/lalinsky/zio/blob/main/docs/tcp-server.md Processes a single client connection by reading lines, sleeping, and echoing them back. Demonstrates asynchronous I/O and concurrent handling. ```zig fn handleClient(allocator: Allocator, stream: Net.Stream) !void { var reader = stream.reader().withCapacity(1024); var writer = stream.writer().withCapacity(1024); while (true) { const line = reader.takeDelimiterInclusiveAligned(allocator, '\n', 1024) catch |err| { if (err == error.EndOfStream) break; std.log.err("Failed to read line: {s}", .{@errorName(err)}); return err; }; defer allocator.free(line); if (std.mem.eql(u8, line, "\n")) { continue; } std.log.debug("Received: {s}", .{line}); try writer.writeAll(line); // Simulate async work try runtime.sleep(1 * runtime.Second); } std.log.info("Client disconnected", .{}); } ``` -------------------------------- ### Add ZIO Dependency Source: https://github.com/lalinsky/zio/blob/main/docs/getting-started.md Fetches and saves the ZIO library as a dependency for your Zig project. ```sh $ zig fetch --save "git+https://github.com/lalinsky/zio#v0.14.0" info: resolved to commit 0000000000000000000000000000000000000000 ``` -------------------------------- ### ZIO Channels for Task Communication Source: https://github.com/lalinsky/zio/blob/main/docs/parallel-grep.md Demonstrates the creation of buffered and unbuffered ZIO channels for passing messages between concurrent tasks. Buffered channels block when full, while unbuffered channels block until a receiver is ready. ```zig --8<-- "examples/parallel_grep.zig:channels" ``` -------------------------------- ### Initialize ZIO Runtime with Auto Executors Source: https://github.com/lalinsky/zio/blob/main/docs/parallel-grep.md Initializes the ZIO runtime to automatically create an executor (OS thread) per CPU core. This is ideal for CPU-bound workloads to achieve true parallelism. ```zig var rt = try zio.Runtime.init(gpa, .{ .executors = .auto }); ``` -------------------------------- ### TCP Echo Server using Zio Native API Source: https://github.com/lalinsky/zio/blob/main/README.md A minimal TCP echo server demonstrating the direct usage of Zio's native API. This approach offers more features but ties the application to the Zio runtime. ```zig const std = @import("std"); const zio = @import("zio"); pub const std_options_debug_io = zio.debug_io; fn handleClient(stream: zio.net.Stream) !void { defer stream.close(); std.log.info("Client connected from {f}", .{stream.socket.address}); var read_buffer: [1024]u8 = undefined; var reader = stream.reader(&read_buffer); var write_buffer: [1024]u8 = undefined; var writer = stream.writer(&write_buffer); while (true) { const line = reader.interface.takeDelimiterInclusive('\n') catch |err| switch (err) { error.EndOfStream => break, else => return err, }; try writer.interface.writeAll(line); try writer.interface.flush(); } } pub fn main() !void { const rt = try zio.Runtime.init(std.heap.smp_allocator, .{}); defer rt.deinit(); const addr = try zio.net.IpAddress.parseIp4("127.0.0.1", 8080); const server = try addr.listen(.{}); defer server.close(); std.log.info("TCP echo server listening on {f}", .{server.socket.address}); var group: zio.Group = .init; defer group.cancel(); while (true) { const stream = try server.accept(.{}); errdefer stream.close(); try group.spawn(handleClient, .{stream}); } } ``` -------------------------------- ### TCP Echo Server using std.Io Interface Source: https://github.com/lalinsky/zio/blob/main/README.md A TCP echo server implemented using the standard library's std.Io interface. This approach is recommended for libraries and offers a more abstract way to handle I/O. ```zig const std = @import("std"); const zio = @import("zio"); const Io = std.Io; fn handleClient(io: Io, stream: Io.net.Stream) Io.Cancelable!void { defer stream.close(io); var read_buffer: [1024]u8 = undefined; var reader = stream.reader(io, &read_buffer); var write_buffer: [1024]u8 = undefined; var writer = stream.writer(io, &write_buffer); while (true) { const line = reader.interface.takeDelimiterInclusive('\n') catch |err| switch (err) { error.EndOfStream => break, error.ReadFailed => return if (reader.err.? == error.Canceled) error.Canceled else {}, else => return, }; writer.interface.writeAll(line) catch return if (writer.err.? == error.Canceled) error.Canceled else {}; writer.interface.flush() catch return if (writer.err.? == error.Canceled) error.Canceled else {}; } } pub fn main() !void { const rt = try zio.Runtime.init(std.heap.smp_allocator, .{}); defer rt.deinit(); const io = rt.io(); const addr = try Io.net.IpAddress.parseIp4("127.0.0.1", 8080); var server = try addr.listen(io, .{}); defer server.deinit(io); var group: Io.Group = .init; defer group.cancel(io); while (true) { const stream = try server.accept(io); errdefer stream.close(io); try group.concurrent(io, handleClient, .{ io, stream }); } } ``` -------------------------------- ### Run Tests Command Source: https://github.com/lalinsky/zio/blob/main/README.md Command to run tests for the Zio project. Options are available to filter specific tests or select a non-default I/O backend. ```bash zig build test -Dtest-filter="foo" -Dbackend=epoll ``` -------------------------------- ### Create Task Group Source: https://github.com/lalinsky/zio/blob/main/docs/tcp-server.md Creates a ZIO Task Group for managing concurrent tasks. When the group is cancelled, all spawned tasks are also cancelled, ensuring proper cleanup. ```zig var group = try runtime.group(); defer group.cancel(); ``` -------------------------------- ### Connect to Server Source: https://github.com/lalinsky/zio/blob/main/docs/tcp-server.md Command to connect to the running TCP echo server using telnet. Used to test the server's functionality by sending and receiving messages. ```sh telnet localhost 8080 ``` -------------------------------- ### Memory Allocation and Transfer via ZIO Channel Source: https://github.com/lalinsky/zio/blob/main/docs/parallel-grep.md Illustrates safe memory management where a worker allocates memory for a search result, transfers ownership via a channel, and the collector frees the memory. This prevents use-after-free or double-free errors. ```zig // In searchFile (called by workers) const result = SearchResult{ .file_path = path, .line_number = line_number, .line = try gpa.dupe(u8, line), // Allocate }; errdefer gpa.free(result.line); // Free if send fails try results_channel.send(result); ``` ```zig // In collector const result = results_channel.receive() catch ... // ... print result ... gpa.free(result.line); // Free ``` -------------------------------- ### Timeout Configuration Source: https://github.com/lalinsky/zio/blob/main/docs/ntp-client.md Defines a timeout duration for network operations. Use `.none` for no timeout or `.deadline` for a specific timestamp. ```zig const request_timeout: zio.Timeout = .{ .duration = .fromSeconds(5) }; ``` -------------------------------- ### Zig Select: Waiting on Multiple Events Source: https://github.com/lalinsky/zio/blob/main/docs/ntp-client.md Use select() to suspend a task until one of several events occurs. Pass a struct with pointers to JoinHandle, Timeout, Signal, Channel, or other awaitables. Returns a union indicating which event fired. ```zig const std = @import("std"); const ntp_client = @import("./ntp_client.zig"); pub fn main() !void { var g = std.heap.GeneralPurposeAllocator(.{}){}; defer _ = g.deinit(); const allocator = g.allocator(); const timer = try ntp_client.Timer.init(allocator, std.time.ns_per_second * 10); defer timer.deinit(); const shutdown = try ntp_client.Shutdown.init(); defer shutdown.deinit(); const result = try ntp_client.select( ntp_client.SelectEvent{.timer = &timer.event}, ntp_client.SelectEvent{.shutdown = &shutdown.event}, ); switch (result) { .timer => std.debug.print("Timer fired!\n", .{}), .shutdown => std.debug.print("Shutdown signal received!\n", .{}), else => unreachable, } } ``` -------------------------------- ### UDP Socket Binding Source: https://github.com/lalinsky/zio/blob/main/docs/ntp-client.md Creates a UDP socket bound to any available network interface and an OS-assigned port. ```zig const socket = try net.UdpSocket.bind(.anyAddress, 0)?; ``` -------------------------------- ### Coordinating Work and Shutdown in ZIO Source: https://github.com/lalinsky/zio/blob/main/docs/parallel-grep.md Orchestrates the entire parallel grep process, including sending work to workers, closing channels for graceful shutdown, and waiting for all tasks to complete. ```zig --8<-- "examples/parallel_grep.zig:coordination" ``` -------------------------------- ### HTTP Server Request Handling Loop Source: https://github.com/lalinsky/zio/blob/main/docs/http-server.md The request handling loop for the HTTP server. It receives HTTP requests and sends responses, supporting HTTP keep-alive for multiple requests over a single connection. The connection is shut down when the client no longer wants keep-alive. ```zig while (server.handleRequest()) |request| { const response = try request.respond(.{ .status = .ok, .body = "Hello from ZIO!\n" }); if (!response.keep_alive) { break; } } ``` -------------------------------- ### NTP Packet Structure Definition Source: https://github.com/lalinsky/zio/blob/main/docs/ntp-client.md Defines the binary structure for NTP packets using Zig's extern struct for C-compatible layout. ```zig const NtpPacket = extern struct { flags: packed struct(u8) { mode: u3 = 3, // Client mode version: u3 = 3, // NTP version 3 leap: u2 = 0, // No leap second warning } = .{}, stratum: u8 = 0, poll: u8 = 0, precision: u8 = 0, root_delay: u32 = 0, root_dispersion: u32 = 0, reference_id: u32 = 0, reference_timestamp: u64 = 0, origin_timestamp: u64 = 0, receive_timestamp: u64 = 0, transmit_timestamp: u64 = 0, }; ``` -------------------------------- ### Receiving UDP Datagrams with Timeout Source: https://github.com/lalinsky/zio/blob/main/docs/ntp-client.md Receives a UDP datagram, returning both the data and the sender's address. Includes a timeout to prevent indefinite waiting. ```zig const result = socket.receiveFrom(&buffer, request_timeout) catch |err| switch (err) { error.Timeout => { log.warn("Request timed out.", .{}); continue; }, else => return err, }; ``` -------------------------------- ### Worker Task Loop for Processing Files Source: https://github.com/lalinsky/zio/blob/main/docs/parallel-grep.md The main loop for a worker task. It receives file paths from a work channel, searches for a pattern, sends results to a results channel, and exits gracefully when the work channel is closed. ```zig --8<-- "examples/parallel_grep.zig:worker" ``` -------------------------------- ### Collector Task for ZIO Results Source: https://github.com/lalinsky/zio/blob/main/docs/parallel-grep.md A dedicated task to collect and print results from the results channel. Running this in a separate task prevents it from blocking the worker tasks. ```zig --8<-- "examples/parallel_grep.zig:collector" ``` -------------------------------- ### Serializing NTP Request Source: https://github.com/lalinsky/zio/blob/main/docs/ntp-client.md Serializes an NTP packet struct into a byte buffer in big-endian format for network transmission. ```zig const request: NtpPacket = .{}; var writer = std.io.Writer.fixed(&buffer[0..@sizeOf(NtpPacket)]); try writer.writeStruct(request, .big); ``` -------------------------------- ### Spawning Worker Tasks in ZIO Source: https://github.com/lalinsky/zio/blob/main/docs/parallel-grep.md Spawns multiple worker tasks that will concurrently process items from a shared work channel. This is a core part of the worker pool pattern. ```zig --8<-- "examples/parallel_grep.zig:spawn_workers" ``` -------------------------------- ### Sending UDP Datagrams Source: https://github.com/lalinsky/zio/blob/main/docs/ntp-client.md Sends a UDP datagram to a specified address. Note that UDP does not guarantee delivery. ```zig try socket.sendTo(&buffer[0..@sizeOf(NtpPacket)], address); ``` -------------------------------- ### Deserializing NTP Response Source: https://github.com/lalinsky/zio/blob/main/docs/ntp-client.md Deserializes a received byte buffer into an NTP packet struct, assuming big-endian encoding. ```zig var reader = std.io.Reader.fixed(result.data[0..result.len]); const response = try reader.takeStruct(NtpPacket, .big); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.