Open fengb opened 5 years ago
Braindump:
const EncodeContext = struct {
suspended: anyframe,
encodeBuffer: []u8,
out: ?[]u8,
fn next(self: *Self, buffer: []u8) ?[]u8 {
if (self.suspended) |frame| {
resume self.frame;
return self.out;
}
return null;
}
}
fn encodeInto(self: Self, ctx: *EncodeContext) void {
// Return value
ctx.suspended = @frame();
const len = write(ctx.buffer);
ctx.output = ctx.buffer[0..len];
suspend;
}
After refactoring a bit, I've found a few things:
encodeInto
takes any writable (any struct with write([]u8) !void
), the write() can be responsible for all the async shenanigans.write([]u8)
is antithetical to multithreading, since each field must be able to write directly into an offset, e.g. write(offset: usize, bytes: []u8)
The initial encoder simply ran the top-level function as a generator. This is a problem for a number of reasons:
A better architecture needs the following: