Request-response
Description
Request-response.
- Main sends an Event (code=42) to the worker's request mailbox.
- Worker adds 1000 to the code, sends it to the response mailbox.
- Main receives the response, verifies the value.
Diagram
main ──Event(code=42)──► req_mbh ──► worker
│ code += 1000
▼
main ◄──Event(code=1042)── resp_mbh ◄── worker
Source
pub fn request_response(allocator: std.mem.Allocator, io: std.Io) !void {
const req_mbh: MailboxHandle = try mailbox.new(io, allocator);
defer mailbox.destroy(req_mbh, allocator);
const resp_mbh: MailboxHandle = try mailbox.new(io, allocator);
defer mailbox.destroy(resp_mbh, allocator);
var ctx: WorkerCtx = .{ .req_mbh = req_mbh, .resp_mbh = resp_mbh, .alloc = allocator };
var fut = try io.concurrent(workerFn, .{&ctx});
{
var slot: Slot = null;
defer items.freeSlot(&slot, allocator);
try items.Event.EventPolyHelper.create(allocator, &slot);
items.Event.EventPolyHelper.mustIdentifySlotAs(&slot).code = 42;
try mailbox.send(req_mbh, &slot);
}
{
var slot: Slot = null;
defer items.freeSlot(&slot, allocator);
try mailbox.receive(resp_mbh, &slot, 5_000_000_000);
const resp: *items.Event = items.Event.EventPolyHelper.identifySlotAs(&slot) orelse return error.WrongTag;
std.log.info("request_response: response code={d}", .{resp.*.code});
try helpers.expect(error.RequestResponseFailed, resp.*.code == 1042, "wrong response code");
}
var rem_req: std.DoublyLinkedList = mailbox.close(req_mbh);
items.freeList(&rem_req, allocator);
fut.await(io);
var rem_resp: std.DoublyLinkedList = mailbox.close(resp_mbh);
items.freeList(&rem_resp, allocator);
}
const WorkerCtx = struct {
req_mbh: MailboxHandle,
resp_mbh: MailboxHandle,
alloc: std.mem.Allocator,
};
fn workerFn(ctx: *WorkerCtx) void {
while (true) {
var slot: Slot = null;
defer items.freeSlot(&slot, ctx.alloc);
mailbox.receive(ctx.req_mbh, &slot, null) catch return;
const ev: *items.Event = items.Event.EventPolyHelper.identifySlotAs(&slot) orelse continue;
std.log.debug("worker: request code={d}", .{ev.*.code});
ev.*.code += 1000;
mailbox.send(ctx.resp_mbh, &slot) catch {};
}
}
const items = @import("../items/items.zig");
const helpers = @import("../helpers/helpers.zig");
const matryoshka = @import("matryoshka");
const std = @import("std");
const polynode = matryoshka.polynode;
const mailbox = matryoshka.mailbox;
const Slot = polynode.Slot;
const MailboxHandle = mailbox.MailboxHandle;