various small backports from main

This commit is contained in:
Karl Seguin
2025-12-19 10:05:42 +08:00
parent 098eeea8f7
commit 566fa72bcd
5 changed files with 77 additions and 7 deletions

View File

@@ -18,7 +18,7 @@ Lightpanda is the open-source browser made for headless usage:
- Javascript execution - Javascript execution
- Support of Web APIs (partial, WIP) - Support of Web APIs (partial, WIP)
- Compatible with Playwright[^1], Puppeteer, chromedp through CDP - Compatible with Playwright[^1], Puppeteer, chromedp through [CDP](https://chromedevtools.github.io/devtools-protocol/)
Fast web automation for AI agents, LLM training, scraping and testing: Fast web automation for AI agents, LLM training, scraping and testing:

View File

@@ -769,6 +769,76 @@ fn _wait(self: *Page, wait_ms: u32) !Session.WaitResult {
} }
} }
fn printWaitAnalysis(self: *Page) void {
std.debug.print("load_state: {s}\n", .{@tagName(self._load_state)});
std.debug.print("parse_state: {s}\n", .{@tagName(std.meta.activeTag(self._parse_state))});
{
std.debug.print("\nactive requests: {d}\n", .{self._session.browser.http_client.active});
var n_ = self._session.browser.http_client.handles.in_use.first;
while (n_) |n| {
const handle: *Http.Client.Handle = @fieldParentPtr("node", n);
const transfer = Http.Transfer.fromEasy(handle.conn.easy) catch |err| {
std.debug.print(" - failed to load transfer: {any}\n", .{err});
break;
};
std.debug.print(" - {f}\n", .{transfer});
n_ = n.next;
}
}
{
std.debug.print("\nqueued requests: {d}\n", .{self._session.browser.http_client.queue.len()});
var n_ = self._session.browser.http_client.queue.first;
while (n_) |n| {
const transfer: *Http.Transfer = @fieldParentPtr("_node", n);
std.debug.print(" - {f}\n", .{transfer});
n_ = n.next;
}
}
{
std.debug.print("\ndeferreds: {d}\n", .{self._script_manager.defer_scripts.len()});
var n_ = self._script_manager.defer_scripts.first;
while (n_) |n| {
const script: *ScriptManager.Script = @fieldParentPtr("node", n);
std.debug.print(" - {s} complete: {any}\n", .{ script.url, script.complete });
n_ = n.next;
}
}
{
std.debug.print("\nasyncs: {d}\n", .{self._script_manager.async_scripts.len()});
}
{
std.debug.print("\nasyncs ready: {d}\n", .{self._script_manager.ready_scripts.len()});
var n_ = self._script_manager.ready_scripts.first;
while (n_) |n| {
const script: *ScriptManager.Script = @fieldParentPtr("node", n);
std.debug.print(" - {s} complete: {any}\n", .{ script.url, script.complete });
n_ = n.next;
}
}
const now = milliTimestamp(.monotonic);
{
std.debug.print("\nhigh_priority schedule: {d}\n", .{self.scheduler.high_priority.count()});
var it = self.scheduler.high_priority.iterator();
while (it.next()) |task| {
std.debug.print(" - {s} schedule: {d}ms\n", .{ task.name, task.run_at - now });
}
}
{
std.debug.print("\nlow_priority schedule: {d}\n", .{self.scheduler.low_priority.count()});
var it = self.scheduler.low_priority.iterator();
while (it.next()) |task| {
std.debug.print(" - {s} schedule: {d}ms\n", .{ task.name, task.run_at - now });
}
}
}
pub fn tick(self: *Page) void { pub fn tick(self: *Page) void {
if (comptime IS_DEBUG) { if (comptime IS_DEBUG) {
log.debug(.page, "tick", .{}); log.debug(.page, "tick", .{});

View File

@@ -20,7 +20,7 @@ const std = @import("std");
const builtin = @import("builtin"); const builtin = @import("builtin");
const log = @import("../log.zig"); const log = @import("../log.zig");
const timestamp = @import("../datetime.zig").milliTimestamp; const milliTimestamp = @import("../datetime.zig").milliTimestamp;
const IS_DEBUG = builtin.mode == .Debug; const IS_DEBUG = builtin.mode == .Debug;
@@ -71,7 +71,7 @@ pub fn add(self: *Scheduler, ctx: *anyopaque, cb: Callback, run_in_ms: u32, opts
.callback = cb, .callback = cb,
.sequence = seq, .sequence = seq,
.name = opts.name, .name = opts.name,
.run_at = timestamp(.monotonic) + run_in_ms, .run_at = milliTimestamp(.monotonic) + run_in_ms,
}); });
} }
@@ -85,7 +85,7 @@ fn runQueue(self: *Scheduler, queue: *Queue) !?u64 {
return null; return null;
} }
const now = timestamp(.monotonic); const now = milliTimestamp(.monotonic);
while (queue.peek()) |*task_| { while (queue.peek()) |*task_| {
if (task_.run_at > now) { if (task_.run_at > now) {

View File

@@ -360,7 +360,7 @@ pub fn preloadImport(self: *ScriptManager, url: [:0]const u8, referrer: []const
// This seems wrong since we're not dealing with an async import (unlike // This seems wrong since we're not dealing with an async import (unlike
// getAsyncModule below), but all we're trying to do here is pre-load the // getAsyncModule below), but all we're trying to do here is pre-load the
// script for execution at some point in the future (when waitForModule is // script for execution at some point in the future (when waitForImport is
// called). // called).
self.async_scripts.append(&script.node); self.async_scripts.append(&script.node);
} }
@@ -564,7 +564,7 @@ fn parseImportmap(self: *ScriptManager, script: *const Script) !void {
} }
} }
const Script = struct { pub const Script = struct {
complete: bool, complete: bool,
kind: Kind, kind: Kind,
status: u16 = 0, status: u16 = 0,