This example demonstrates how to initialize a multi-threaded Tardy instance, bind a Socket to a host/port, and use rt.spawn to handle incoming connections using coroutines (Frames).
const std = @import("std");
const options = @import("options");
const tardy = @import("tardy");
const Runtime = tardy.Runtime;
const Socket = tardy.net.Socket;
const AsyncIO = tardy.AsyncIO;
const backend: AsyncIO.Kind = .init(options.async_backend);
const Tardy = tardy.Tardy(backend);
fn echo_frame(rt: *Runtime, server: *const Socket) !void {
const socket = try server.accept(rt);
defer socket.close_blocking();
var sock_reader = socket.reader(rt, &.{});
const sock_r = &sock_reader.interface;
var sock_writer = socket.writer(rt, &.{});
const sock_w = &sock_writer.interface;
defer sock_w.flush() catch unreachable;
// spawn off a new frame.
try rt.spawn(echo_frame, .{ rt, server }, .@"16KiB");
var buffer: [501]u8 = undefined;
while (true) {
const recv_length = sock_r.readSliceShort(&buffer) catch |e| {
break;
};
if (recv_length == 0) return;
sock_w.writeAll(buffer[0..recv_length]) catch |e| {
break;
};
}
}
pub fn main(init: std.process.Init) !void {
const host = "0.0.0.0";
const port = 9862;
const server: Socket = try .init(
init.io,
.{ .tcp = .{ .host = host, .port = port } },
);
try server.bind();
try server.listen(501);
var td: Tardy = try .init(init.gpa, init.io, .{
.pooling = .static,
.size_tasks_initial = 256,
.size_aio_reap_max = 256,
});
defer td.deinit();
try td.entry(
&server,
struct {
fn start(rt: *Runtime, tcp_server: *const Socket) !void {
try rt.spawn(echo_frame, .{ rt, tcp_server }, .@"32KiB");
}
}.start,
);
}