server: handle close and re-open connection

Signed-off-by: Francis Bouvier <francis@lightpanda.io>
This commit is contained in:
Francis Bouvier
2024-10-08 16:22:24 +02:00
parent 76a9034668
commit 49adb61146

View File

@@ -23,6 +23,7 @@ const Completion = public.IO.Completion;
const AcceptError = public.IO.AcceptError; const AcceptError = public.IO.AcceptError;
const RecvError = public.IO.RecvError; const RecvError = public.IO.RecvError;
const SendError = public.IO.SendError; const SendError = public.IO.SendError;
const CloseError = public.IO.CloseError;
const TimeoutError = public.IO.TimeoutError; const TimeoutError = public.IO.TimeoutError;
const MsgBuffer = @import("msg.zig").MsgBuffer; const MsgBuffer = @import("msg.zig").MsgBuffer;
@@ -30,7 +31,7 @@ const Browser = @import("browser/browser.zig").Browser;
const cdp = @import("cdp/cdp.zig"); const cdp = @import("cdp/cdp.zig");
const NoError = error{NoError}; const NoError = error{NoError};
const IOError = AcceptError || RecvError || SendError || TimeoutError; const IOError = AcceptError || RecvError || SendError || CloseError || TimeoutError;
const Error = IOError || std.fmt.ParseIntError || cdp.Error || NoError; const Error = IOError || std.fmt.ParseIntError || cdp.Error || NoError;
// I/O Recv // I/O Recv
@@ -47,6 +48,9 @@ pub const Cmd = struct {
buf: []u8, // only for read operations buf: []u8, // only for read operations
err: ?Error = null, err: ?Error = null,
completion: *Completion,
acceptCtx: *Accept = undefined,
msg_buf: *MsgBuffer, msg_buf: *MsgBuffer,
// CDP // CDP
@@ -83,7 +87,9 @@ pub const Cmd = struct {
// read and execute input // read and execute input
self.msg_buf.read(self.alloc(), input, self, Cmd.do) catch |err| { self.msg_buf.read(self.alloc(), input, self, Cmd.do) catch |err| {
std.log.err("do error: {any}", .{err}); if (err != error.Closed) {
std.log.err("do error: {any}", .{err});
}
return; return;
}; };
@@ -101,8 +107,20 @@ pub const Cmd = struct {
return self.browser.currentSession().env; return self.browser.currentSession().env;
} }
// actions
// -------
fn do(self: *Cmd, cmd: []const u8) anyerror!void { fn do(self: *Cmd, cmd: []const u8) anyerror!void {
// close cmd
if (std.mem.eql(u8, cmd, "close")) {
self.loop.io.close(*Cmd, self, Cmd.closeCbk, self.completion, self.socket);
return error.Closed;
}
// cdp cmd
const res = cdp.do(self.alloc(), cmd, self) catch |err| { const res = cdp.do(self.alloc(), cmd, self) catch |err| {
// cdp end
if (err == error.DisposeBrowserContext) { if (err == error.DisposeBrowserContext) {
try self.newSession(); try self.newSession();
return; return;
@@ -124,6 +142,17 @@ pub const Cmd = struct {
try self.browser.currentSession().setInspector(cmd_opaque, Cmd.onInspectorResp, Cmd.onInspectorNotif); try self.browser.currentSession().setInspector(cmd_opaque, Cmd.onInspectorResp, Cmd.onInspectorNotif);
} }
fn closeCbk(self: *Cmd, completion: *Completion, result: CloseError!void) void {
_ = result catch |err| {
self.err = err;
return;
};
std.log.debug("conn closed", .{});
// continue accepting incoming requests
self.loop.io.accept(*Accept, self.acceptCtx, Accept.cbk, completion, self.acceptCtx.socket);
}
// Inspector // Inspector
pub fn sendInspector(self: *Cmd, msg: []const u8) void { pub fn sendInspector(self: *Cmd, msg: []const u8) void {
@@ -264,12 +293,14 @@ pub fn listen(browser: *Browser, loop: *public.Loop, socket: std.posix.socket_t)
// create I/O contexts and callbacks // create I/O contexts and callbacks
// for accepting connections and receving messages // for accepting connections and receving messages
var ctxInput: [BufReadSize]u8 = undefined; var ctxInput: [BufReadSize]u8 = undefined;
var completion: Completion = undefined;
var cmd = Cmd{ var cmd = Cmd{
.loop = loop, .loop = loop,
.browser = browser, .browser = browser,
.socket = undefined, .socket = undefined,
.buf = &ctxInput, .buf = &ctxInput,
.msg_buf = &msg_buf, .msg_buf = &msg_buf,
.completion = &completion,
}; };
const cmd_opaque = @as(*anyopaque, @ptrCast(&cmd)); const cmd_opaque = @as(*anyopaque, @ptrCast(&cmd));
try browser.currentSession().setInspector(cmd_opaque, Cmd.onInspectorResp, Cmd.onInspectorNotif); try browser.currentSession().setInspector(cmd_opaque, Cmd.onInspectorResp, Cmd.onInspectorNotif);
@@ -278,9 +309,9 @@ pub fn listen(browser: *Browser, loop: *public.Loop, socket: std.posix.socket_t)
.cmd = &cmd, .cmd = &cmd,
.socket = socket, .socket = socket,
}; };
cmd.acceptCtx = &accept;
// accepting connection asynchronously on internal server // accepting connection asynchronously on internal server
var completion: Completion = undefined;
loop.io.accept(*Accept, &accept, Accept.cbk, &completion, socket); loop.io.accept(*Accept, &accept, Accept.cbk, &completion, socket);
// infinite loop on I/O events, either: // infinite loop on I/O events, either: