mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 23:23:28 +00:00
Rework page wait again
Further reducing bouncing between page and server for loop polling. If there is a page, the page polls. If there isn't a page, the server polls. Simpler.
This commit is contained in:
@@ -124,48 +124,58 @@ pub const Server = struct {
|
||||
client.* = try Client.init(socket, self);
|
||||
defer client.deinit();
|
||||
|
||||
var last_message = timestamp();
|
||||
var http = &self.app.http;
|
||||
|
||||
http.monitorSocket(socket);
|
||||
defer http.unmonitorSocket();
|
||||
|
||||
std.debug.assert(client.mode == .http);
|
||||
while (true) {
|
||||
if (http.poll(10) == .extra_socket) {
|
||||
const n = posix.read(socket, client.readBuf()) catch |err| {
|
||||
log.warn(.app, "CDP read", .{ .err = err });
|
||||
return;
|
||||
};
|
||||
if (n == 0) {
|
||||
log.info(.app, "CDP disconnect", .{});
|
||||
return;
|
||||
}
|
||||
const more = client.processData(n) catch false;
|
||||
if (!more) {
|
||||
return;
|
||||
}
|
||||
last_message = timestamp();
|
||||
} else if (timestamp() - last_message > timeout_ms) {
|
||||
if (http.poll(timeout_ms) != .extra_socket) {
|
||||
log.info(.app, "CDP timeout", .{});
|
||||
return;
|
||||
}
|
||||
// We have 3 types of "events":
|
||||
// - Incoming CDP messages
|
||||
// - Network events from the browser
|
||||
// - Timeouts from the browser
|
||||
|
||||
// The call to http.poll above handles the first two (which is why
|
||||
// we pass the client socket to it). But browser timeouts aren't
|
||||
// hooked into that. So we need to go to the browser page (if there
|
||||
// is one), and ask it to process any pending events. That action
|
||||
// doesn't starve #2 (Network events from the browser), because
|
||||
// page.wait() handles that too. But it does starve #1 (Incoming CDP
|
||||
// messages). The good news is that, while the Page is mostly
|
||||
// unaware of CDP, it will only block if it actually has something to
|
||||
// do AND it knows if we're waiting on an intercept request, and will
|
||||
// eagerly return control here in those cases.
|
||||
if (try client.readSocket() == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (client.mode == .cdp) {
|
||||
client.mode.cdp.pageWait();
|
||||
break; // switch to our CDP loop
|
||||
}
|
||||
}
|
||||
|
||||
var cdp = &client.mode.cdp;
|
||||
var last_message = timestamp();
|
||||
var ms_remaining = timeout_ms;
|
||||
while (true) {
|
||||
switch (cdp.pageWait(ms_remaining)) {
|
||||
.extra_socket => {
|
||||
if (try client.readSocket() == false) {
|
||||
return;
|
||||
}
|
||||
last_message = timestamp();
|
||||
ms_remaining = timeout_ms;
|
||||
},
|
||||
.no_page => {
|
||||
if (http.poll(ms_remaining) != .extra_socket) {
|
||||
log.info(.app, "CDP timeout", .{});
|
||||
return;
|
||||
}
|
||||
if (try client.readSocket() == false) {
|
||||
return;
|
||||
}
|
||||
last_message = timestamp();
|
||||
ms_remaining = timeout_ms;
|
||||
},
|
||||
.done => {
|
||||
std.debug.print("ok\n", .{});
|
||||
const elapsed = timestamp() - last_message;
|
||||
if (elapsed > ms_remaining) {
|
||||
log.info(.app, "CDP timeout", .{});
|
||||
return;
|
||||
}
|
||||
ms_remaining -= @as(i32, @intCast(elapsed));
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -222,6 +232,20 @@ pub const Client = struct {
|
||||
self.send_arena.deinit();
|
||||
}
|
||||
|
||||
fn readSocket(self: *Client) !bool {
|
||||
const n = posix.read(self.socket, self.readBuf()) catch |err| {
|
||||
log.warn(.app, "CDP read", .{ .err = err });
|
||||
return false;
|
||||
};
|
||||
|
||||
if (n == 0) {
|
||||
log.info(.app, "CDP disconnect", .{});
|
||||
return false;
|
||||
}
|
||||
|
||||
return self.processData(n) catch false;
|
||||
}
|
||||
|
||||
fn readBuf(self: *Client) []u8 {
|
||||
return self.reader.readBuf();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user