mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-22 04:34:44 +00:00
Merge pull request #1651 from lightpanda-io/more_pump_message_loop
Run the MessageLoop [a lot] more.
This commit is contained in:
2
.github/actions/install/action.yml
vendored
2
.github/actions/install/action.yml
vendored
@@ -13,7 +13,7 @@ inputs:
|
||||
zig-v8:
|
||||
description: 'zig v8 version to install'
|
||||
required: false
|
||||
default: 'v0.3.0'
|
||||
default: 'v0.3.1'
|
||||
v8:
|
||||
description: 'v8 version to install'
|
||||
required: false
|
||||
|
||||
@@ -3,7 +3,7 @@ FROM debian:stable-slim
|
||||
ARG MINISIG=0.12
|
||||
ARG ZIG_MINISIG=RWSGOq2NVecA2UPNdBUZykf1CCb147pkmdtYxgb3Ti+JO/wCYvhbAb/U
|
||||
ARG V8=14.0.365.4
|
||||
ARG ZIG_V8=v0.3.0
|
||||
ARG ZIG_V8=v0.3.1
|
||||
ARG TARGETPLATFORM
|
||||
|
||||
RUN apt-get update -yq && \
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
.minimum_zig_version = "0.15.2",
|
||||
.dependencies = .{
|
||||
.v8 = .{
|
||||
.url = "https://github.com/lightpanda-io/zig-v8-fork/archive/refs/tags/v0.3.0.tar.gz",
|
||||
.hash = "v8-0.0.0-xddH69R6BADRXsnhjA8wNnfKfLQACF1I7CSTZvsMAvp8",
|
||||
.url = "https://github.com/lightpanda-io/zig-v8-fork/archive/refs/tags/v0.3.1.tar.gz",
|
||||
.hash = "v8-0.0.0-xddH64J7BAC81mkf6G9RbEJxS-W3TIRl5iFnShwbqCqy",
|
||||
|
||||
},
|
||||
//.v8 = .{ .path = "../zig-v8-fork" },
|
||||
.@"boringssl-zig" = .{
|
||||
|
||||
@@ -92,10 +92,24 @@ pub fn runMicrotasks(self: *Browser) void {
|
||||
}
|
||||
|
||||
pub fn runMacrotasks(self: *Browser) !?u64 {
|
||||
return try self.env.runMacrotasks();
|
||||
const env = &self.env;
|
||||
|
||||
const time_to_next = try self.env.runMacrotasks();
|
||||
env.pumpMessageLoop();
|
||||
|
||||
// either of the above could have queued more microtasks
|
||||
env.runMicrotasks();
|
||||
|
||||
return time_to_next;
|
||||
}
|
||||
|
||||
pub fn runMessageLoop(self: *const Browser) void {
|
||||
self.env.pumpMessageLoop();
|
||||
pub fn hasBackgroundTasks(self: *Browser) bool {
|
||||
return self.env.hasBackgroundTasks();
|
||||
}
|
||||
pub fn waitForBackgroundTasks(self: *Browser) void {
|
||||
self.env.waitForBackgroundTasks();
|
||||
}
|
||||
|
||||
pub fn runIdleTasks(self: *const Browser) void {
|
||||
self.env.runIdleTasks();
|
||||
}
|
||||
|
||||
@@ -314,12 +314,12 @@ pub fn init(self: *Page, id: u32, session: *Session, parent: ?*Page) !void {
|
||||
if (comptime builtin.is_test == false) {
|
||||
// HTML test runner manually calls these as necessary
|
||||
try self.js.scheduler.add(session.browser, struct {
|
||||
fn runMessageLoop(ctx: *anyopaque) !?u32 {
|
||||
fn runIdleTasks(ctx: *anyopaque) !?u32 {
|
||||
const b: *@import("Browser.zig") = @ptrCast(@alignCast(ctx));
|
||||
b.runMessageLoop();
|
||||
return 250;
|
||||
b.runIdleTasks();
|
||||
return 200;
|
||||
}
|
||||
}.runMessageLoop, 250, .{ .name = "page.messageLoop" });
|
||||
}.runIdleTasks, 200, .{ .name = "page.runIdleTasks", .low_priority = true });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -873,8 +873,7 @@ pub const Script = struct {
|
||||
}
|
||||
|
||||
defer {
|
||||
// We should run microtasks even if script execution fails.
|
||||
local.runMicrotasks();
|
||||
local.runMacrotasks(); // also runs microtasks
|
||||
_ = page.js.scheduler.run() catch |err| {
|
||||
log.err(.page, "scheduler", .{ .err = err });
|
||||
};
|
||||
|
||||
@@ -258,7 +258,7 @@ fn _wait(self: *Session, page: *Page, wait_ms: u32) !WaitResult {
|
||||
std.debug.assert(http_client.intercepted == 0);
|
||||
}
|
||||
|
||||
const ms = ms_to_next_task orelse blk: {
|
||||
const ms: u64 = ms_to_next_task orelse blk: {
|
||||
if (wait_ms - ms_remaining < 100) {
|
||||
if (comptime builtin.is_test) {
|
||||
return .done;
|
||||
@@ -268,6 +268,14 @@ fn _wait(self: *Session, page: *Page, wait_ms: u32) !WaitResult {
|
||||
// background jobs.
|
||||
break :blk 50;
|
||||
}
|
||||
|
||||
if (browser.hasBackgroundTasks()) {
|
||||
// _we_ have nothing to run, but v8 is working on
|
||||
// background tasks. We'll wait for them.
|
||||
browser.waitForBackgroundTasks();
|
||||
break :blk 20;
|
||||
}
|
||||
|
||||
// No http transfers, no cdp extra socket, no
|
||||
// scheduled tasks, we're done.
|
||||
return .done;
|
||||
@@ -293,8 +301,14 @@ fn _wait(self: *Session, page: *Page, wait_ms: u32) !WaitResult {
|
||||
// an cdp_socket registered with the http client).
|
||||
// We should continue to run lowPriority tasks, so we
|
||||
// minimize how long we'll poll for network I/O.
|
||||
const ms_to_wait = @min(200, @min(ms_remaining, ms_to_next_task orelse 200));
|
||||
if (try http_client.tick(ms_to_wait) == .cdp_socket) {
|
||||
var ms_to_wait = @min(200, ms_to_next_task orelse 200);
|
||||
if (ms_to_wait > 10 and browser.hasBackgroundTasks()) {
|
||||
// if we have background tasks, we don't want to wait too
|
||||
// long for a message from the client. We want to go back
|
||||
// to the top of the loop and run macrotasks.
|
||||
ms_to_wait = 10;
|
||||
}
|
||||
if (try http_client.tick(@min(ms_remaining, ms_to_wait)) == .cdp_socket) {
|
||||
// data on a socket we aren't handling, return to caller
|
||||
return .cdp_socket;
|
||||
}
|
||||
|
||||
@@ -237,7 +237,7 @@ pub fn deinit(self: *Context) void {
|
||||
env.isolate.notifyContextDisposed();
|
||||
// There can be other tasks associated with this context that we need to
|
||||
// purge while the context is still alive.
|
||||
env.pumpMessageLoop();
|
||||
_ = env.pumpMessageLoop();
|
||||
v8.v8__MicrotaskQueue__DELETE(self.microtask_queue);
|
||||
}
|
||||
|
||||
|
||||
@@ -397,10 +397,23 @@ pub fn pumpMessageLoop(self: *const Env) void {
|
||||
|
||||
const isolate = self.isolate.handle;
|
||||
const platform = self.platform.handle;
|
||||
while (v8.v8__Platform__PumpMessageLoop(platform, isolate, false)) {
|
||||
if (comptime IS_DEBUG) {
|
||||
log.debug(.browser, "pumpMessageLoop", .{});
|
||||
}
|
||||
while (v8.v8__Platform__PumpMessageLoop(platform, isolate, false)) {}
|
||||
}
|
||||
|
||||
pub fn hasBackgroundTasks(self: *const Env) bool {
|
||||
return v8.v8__Isolate__HasPendingBackgroundTasks(self.isolate.handle);
|
||||
}
|
||||
|
||||
pub fn waitForBackgroundTasks(self: *Env) void {
|
||||
var hs: v8.HandleScope = undefined;
|
||||
v8.v8__HandleScope__CONSTRUCT(&hs, self.isolate.handle);
|
||||
defer v8.v8__HandleScope__DESTRUCT(&hs);
|
||||
|
||||
const isolate = self.isolate.handle;
|
||||
const platform = self.platform.handle;
|
||||
while (v8.v8__Isolate__HasPendingBackgroundTasks(isolate)) {
|
||||
_ = v8.v8__Platform__PumpMessageLoop(platform, isolate, true);
|
||||
self.runMicrotasks();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -82,6 +82,12 @@ pub fn createTypedArray(self: *const Local, comptime array_type: js.ArrayType, s
|
||||
return .init(self, size);
|
||||
}
|
||||
|
||||
pub fn runMacrotasks(self: *const Local) void {
|
||||
const env = self.ctx.env;
|
||||
env.pumpMessageLoop();
|
||||
env.runMicrotasks(); // macrotasks can cause microtasks to queue
|
||||
}
|
||||
|
||||
pub fn runMicrotasks(self: *const Local) void {
|
||||
self.ctx.env.runMicrotasks();
|
||||
}
|
||||
|
||||
@@ -436,17 +436,18 @@ pub fn BrowserContext(comptime CDP_T: type) type {
|
||||
|
||||
pub fn deinit(self: *Self) void {
|
||||
const browser = &self.cdp.browser;
|
||||
const env = &browser.env;
|
||||
|
||||
// Drain microtasks makes sure we don't have inspector's callback
|
||||
// in progress before deinit.
|
||||
browser.env.runMicrotasks();
|
||||
env.runMicrotasks();
|
||||
|
||||
// resetContextGroup detach the inspector from all contexts.
|
||||
// It append async tasks, so we make sure we run the message loop
|
||||
// before deinit it.
|
||||
browser.env.inspector.?.resetContextGroup();
|
||||
browser.runMessageLoop();
|
||||
browser.env.inspector.?.stopSession();
|
||||
env.inspector.?.resetContextGroup();
|
||||
_ = env.pumpMessageLoop();
|
||||
env.inspector.?.stopSession();
|
||||
|
||||
// abort all intercepted requests before closing the sesion/page
|
||||
// since some of these might callback into the page/scriptmanager
|
||||
|
||||
Reference in New Issue
Block a user