Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,6 @@ fn addDependencies(b: *Build, mod: *Build.Module, opts: *Build.Step.Options) !vo
.optimize = mod.optimize.?,
};

mod.addImport("tigerbeetle-io", b.dependency("tigerbeetle_io", .{}).module("tigerbeetle_io"));

mod.addIncludePath(b.path("vendor/lightpanda"));

{
Expand Down
5 changes: 0 additions & 5 deletions build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,10 @@
.version = "0.0.0",
.fingerprint = 0xda130f3af836cea0,
.dependencies = .{
.tigerbeetle_io = .{
.url = "https://github.com/lightpanda-io/tigerbeetle-io/archive/19ae89eb3814d48c202ac9e0495fc5cadb29dfe7.tar.gz",
.hash = "tigerbeetle_io-0.0.0-ViLgxjqSBADhuHO_RZm4yNzuoKDXWP39hDn60Kht40OC",
},
.v8 = .{
.url = "https://github.com/lightpanda-io/zig-v8-fork/archive/cf412d5b3d9d608582571d821e0d552337ef690d.tar.gz",
.hash = "v8-0.0.0-xddH69zDAwA4fp1dBo_jEDjS5bhXycPwRlZHp6_X890t",
},
//.v8 = .{ .path = "../zig-v8-fork" },
//.tigerbeetle_io = .{ .path = "../tigerbeetle-io" },
},
}
11 changes: 0 additions & 11 deletions src/app.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ const Allocator = std.mem.Allocator;

const log = @import("log.zig");
const Http = @import("http/Http.zig");
const Loop = @import("runtime/loop.zig").Loop;
const Platform = @import("runtime/js.zig").Platform;

const Telemetry = @import("telemetry/telemetry.zig").Telemetry;
Expand All @@ -14,7 +13,6 @@ const Notification = @import("notification.zig").Notification;
// might need.
pub const App = struct {
http: Http,
loop: *Loop,
config: Config,
platform: ?*const Platform,
allocator: Allocator,
Expand Down Expand Up @@ -45,12 +43,6 @@ pub const App = struct {
const app = try allocator.create(App);
errdefer allocator.destroy(app);

const loop = try allocator.create(Loop);
errdefer allocator.destroy(loop);

loop.* = try Loop.init(allocator);
errdefer loop.deinit();

const notification = try Notification.init(allocator, null);
errdefer notification.deinit();

Expand All @@ -68,7 +60,6 @@ pub const App = struct {
const app_dir_path = getAndMakeAppDir(allocator);

app.* = .{
.loop = loop,
.http = http,
.allocator = allocator,
.telemetry = undefined,
Expand All @@ -92,8 +83,6 @@ pub const App = struct {
allocator.free(app_dir_path);
}
self.telemetry.deinit();
self.loop.deinit();
allocator.destroy(self.loop);
self.notification.deinit();
self.http.deinit();
allocator.destroy(self);
Expand Down
6 changes: 3 additions & 3 deletions src/browser/Scheduler.zig
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,15 @@ pub fn add(self: *Scheduler, ctx: *anyopaque, func: Task.Func, ms: u32, opts: Ad
});
}

pub fn runHighPriority(self: *Scheduler) !?u32 {
pub fn runHighPriority(self: *Scheduler) !?i32 {
return self.runQueue(&self.primary);
}

pub fn runLowPriority(self: *Scheduler) !?u32 {
pub fn runLowPriority(self: *Scheduler) !?i32 {
return self.runQueue(&self.secondary);
}

fn runQueue(self: *Scheduler, queue: *Queue) !?u32 {
fn runQueue(self: *Scheduler, queue: *Queue) !?i32 {
// this is O(1)
if (queue.count() == 0) {
return null;
Expand Down
2 changes: 1 addition & 1 deletion src/browser/ScriptManager.zig
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ pub fn blockingGet(self: *ScriptManager, url: [:0]const u8) !BlockingResult {

// rely on http's timeout settings to avoid an endless/long loop.
while (true) {
try client.tick(200);
_ = try client.tick(.{ .timeout_ms = 200 });
switch (blocking.state) {
.running => {},
.done => |result| return result,
Expand Down
21 changes: 7 additions & 14 deletions src/browser/page.zig
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,6 @@ const polyfill = @import("polyfill/polyfill.zig");
pub const Page = struct {
cookie_jar: *storage.CookieJar,

// Pre-configured http/cilent.zig used to make HTTP requests.
// @newhttp
// request_factory: RequestFactory,

session: *Session,

// An arena with a lifetime for the entire duration of the page
Expand Down Expand Up @@ -146,12 +142,9 @@ pub const Page = struct {
.scheduler = Scheduler.init(arena),
.keydown_event_node = .{ .func = keydownCallback },
.window_clicked_event_node = .{ .func = windowClicked },
// @newhttp
// .request_factory = browser.http_client.requestFactory(.{
// .notification = browser.notification,
// }),
.main_context = undefined,
};

self.main_context = try session.executor.createJsContext(&self.window, self, self, true, Env.GlobalMissingCallback.init(&self.polyfill_loader));
try polyfill.preload(self.arena, self.main_context);

Expand Down Expand Up @@ -269,7 +262,7 @@ pub const Page = struct {
return self.script_manager.blockingGet(src);
}

pub fn wait(self: *Page, wait_sec: usize) void {
pub fn wait(self: *Page, wait_sec: u16) void {
self._wait(wait_sec) catch |err| switch (err) {
error.JsError => {}, // already logged (with hopefully more context)
else => {
Expand All @@ -283,9 +276,9 @@ pub const Page = struct {
};
}

fn _wait(self: *Page, wait_sec: usize) !void {
var ms_remaining = wait_sec * 1000;
fn _wait(self: *Page, wait_sec: u16) !void {
var timer = try std.time.Timer.start();
var ms_remaining: i32 = @intCast(wait_sec * 1000);

var try_catch: Env.TryCatch = undefined;
try_catch.init(self.main_context);
Expand Down Expand Up @@ -320,7 +313,7 @@ pub const Page = struct {
}

// There should only be 1 active http transfer, the main page
try http_client.tick(ms_remaining);
_ = try http_client.tick(.{ .timeout_ms = ms_remaining });
},
.html, .parsed => {
// The HTML page was parsed. We now either have JS scripts to
Expand Down Expand Up @@ -381,7 +374,7 @@ pub const Page = struct {
// inflight requests
else @min(ms_remaining, ms_to_next_task orelse 1000);

try http_client.tick(ms_to_wait);
_ = try http_client.tick(.{ .timeout_ms = ms_to_wait });

if (request_intercepted) {
// Again, proritizing intercepted requests. Exit this
Expand All @@ -401,7 +394,7 @@ pub const Page = struct {
if (ms_elapsed >= ms_remaining) {
return;
}
ms_remaining -= ms_elapsed;
ms_remaining -= @intCast(ms_elapsed);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/browser/session.zig
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ pub const Session = struct {
return &(self.page orelse return null);
}

pub fn wait(self: *Session, wait_sec: usize) void {
pub fn wait(self: *Session, wait_sec: u16) void {
if (self.queued_navigation) |qn| {
// This was already aborted on the page, but it would be pretty
// bad if old requests went to the new page, so let's make double sure
Expand Down
16 changes: 6 additions & 10 deletions src/cdp/cdp.zig
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,9 @@ pub fn CDPT(comptime TypeProvider: type) type {
}

// @newhttp
// A bit hacky right now. The main server loop blocks only for CDP
// messages. It no longer blocks for page timeouts of page HTTP
// transfers. So we need to call this more ourselves.
// This is called after every message and [very hackily] from the server
// loop.
// This is hopefully temporary.
// A bit hacky right now. The main server loop doesn't unblock for
// scheduled task. So we run this directly in order to process any
// timeouts (or http events) which are ready to be processed.
pub fn pageWait(self: *Self) void {
const session = &(self.browser.session orelse return);
// exits early if there's nothing to do, so a large value like
Expand Down Expand Up @@ -592,8 +589,7 @@ pub fn BrowserContext(comptime CDP_T: type) type {
};

const cdp = self.cdp;
var arena = std.heap.ArenaAllocator.init(cdp.allocator);
errdefer arena.deinit();
const allocator = cdp.client.send_arena.allocator();

const field = ",\"sessionId\":\"";

Expand All @@ -602,7 +598,7 @@ pub fn BrowserContext(comptime CDP_T: type) type {
const message_len = msg.len + session_id.len + 1 + field.len + 10;

var buf: std.ArrayListUnmanaged(u8) = .{};
buf.ensureTotalCapacity(arena.allocator(), message_len) catch |err| {
buf.ensureTotalCapacity(allocator, message_len) catch |err| {
log.err(.cdp, "inspector buffer", .{ .err = err });
return;
};
Expand All @@ -617,7 +613,7 @@ pub fn BrowserContext(comptime CDP_T: type) type {
buf.appendSliceAssumeCapacity("\"}");
std.debug.assert(buf.items.len == message_len);

try cdp.client.sendJSONRaw(arena, buf);
try cdp.client.sendJSONRaw(buf);
}
};
}
Expand Down
4 changes: 3 additions & 1 deletion src/cdp/testing.zig
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,14 @@ pub const Document = @import("../testing.zig").Document;

const Client = struct {
allocator: Allocator,
send_arena: ArenaAllocator,
sent: std.ArrayListUnmanaged(json.Value) = .{},
serialized: std.ArrayListUnmanaged([]const u8) = .{},

fn init(alloc: Allocator) Client {
return .{
.allocator = alloc,
.send_arena = ArenaAllocator.init(alloc),
};
}

Expand All @@ -58,7 +60,7 @@ const Client = struct {
try self.sent.append(self.allocator, value);
}

pub fn sendJSONRaw(self: *Client, _: ArenaAllocator, buf: std.ArrayListUnmanaged(u8)) !void {
pub fn sendJSONRaw(self: *Client, buf: std.ArrayListUnmanaged(u8)) !void {
const value = try json.parseFromSliceLeaky(json.Value, self.allocator, buf.items, .{});
try self.sent.append(self.allocator, value);
}
Expand Down
35 changes: 25 additions & 10 deletions src/http/Client.zig
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const CookieJar = @import("../browser/storage/storage.zig").CookieJar;
const urlStitch = @import("../url.zig").stitch;

const c = Http.c;
const posix = std.posix;

const Allocator = std.mem.Allocator;
const ArenaAllocator = std.heap.ArenaAllocator;
Expand Down Expand Up @@ -167,22 +168,24 @@ pub fn abort(self: *Client) void {
}
}

pub fn tick(self: *Client, timeout_ms: usize) !void {
var handles = &self.handles;
const TickOpts = struct {
timeout_ms: i32 = 0,
poll_socket: ?posix.socket_t = null,
};
pub fn tick(self: *Client, opts: TickOpts) !bool {
while (true) {
if (handles.hasAvailable() == false) {
if (self.handles.hasAvailable() == false) {
break;
}
const queue_node = self.queue.popFirst() orelse break;
const req = queue_node.data;
self.queue_node_pool.destroy(queue_node);

// we know this exists, because we checked isEmpty() above
const handle = handles.getFreeHandle().?;
const handle = self.handles.getFreeHandle().?;
try self.makeRequest(handle, req);
}

try self.perform(@intCast(timeout_ms));
return self.perform(opts.timeout_ms, opts.poll_socket);
}

pub fn request(self: *Client, req: Request) !void {
Expand Down Expand Up @@ -343,16 +346,26 @@ fn makeRequest(self: *Client, handle: *Handle, transfer: *Transfer) !void {
}

self.active += 1;
return self.perform(0);
_ = try self.perform(0, null);
}

fn perform(self: *Client, timeout_ms: c_int) !void {
fn perform(self: *Client, timeout_ms: c_int, socket: ?posix.socket_t) !bool {
const multi = self.multi;

var running: c_int = undefined;
try errorMCheck(c.curl_multi_perform(multi, &running));

if (running > 0 and timeout_ms > 0) {
if (socket) |s| {
var wait_fd = c.curl_waitfd{
.fd = s,
.events = c.CURL_WAIT_POLLIN,
.revents = 0,
};
try errorMCheck(c.curl_multi_poll(multi, &wait_fd, 1, timeout_ms, null));
if (wait_fd.revents != 0) {
// the extra socket we passed in is ready, let's signal our caller
return true;
}
} else if (running > 0 and timeout_ms > 0) {
try errorMCheck(c.curl_multi_poll(multi, null, 0, timeout_ms, null));
}

Expand Down Expand Up @@ -388,6 +401,8 @@ fn perform(self: *Client, timeout_ms: c_int) !void {
self.requestFailed(transfer, err);
}
}

return false;
}

fn endTransfer(self: *Client, transfer: *Transfer) void {
Expand Down
12 changes: 12 additions & 0 deletions src/http/Http.zig
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.

const std = @import("std");
const posix = std.posix;

pub const c = @cImport({
@cInclude("curl/curl.h");
Expand All @@ -26,6 +27,7 @@ pub const ENABLE_DEBUG = false;
pub const Client = @import("Client.zig");
pub const Transfer = Client.Transfer;

const log = @import("../log.zig");
const errors = @import("errors.zig");

const Allocator = std.mem.Allocator;
Expand Down Expand Up @@ -85,6 +87,16 @@ pub fn deinit(self: *Http) void {
self.arena.deinit();
}

pub fn poll(self: *Http, timeout_ms: i32, socket: posix.socket_t) bool {
return self.client.tick(.{
.timeout_ms = timeout_ms,
.poll_socket = socket,
}) catch |err| {
log.err(.app, "http poll", .{ .err = err });
return false;
};
}

pub fn newConnection(self: *Http) !Connection {
return Connection.init(self.ca_blob, &self.opts);
}
Expand Down
12 changes: 8 additions & 4 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ const builtin = @import("builtin");
const Allocator = std.mem.Allocator;

const log = @import("log.zig");
const server = @import("server.zig");
const App = @import("app.zig").App;
const Server = @import("server.zig").Server;
const Http = @import("http/Http.zig");
const Platform = @import("runtime/js.zig").Platform;
const Browser = @import("browser/browser.zig").Browser;
Expand Down Expand Up @@ -103,8 +103,10 @@ fn run(alloc: Allocator) !void {
return args.printUsageAndExit(false);
};

const timeout = std.time.ns_per_s * @as(u64, opts.timeout);
server.run(app, address, timeout) catch |err| {
var server = try Server.init(app, address);
defer server.deinit();

server.run(address, opts.timeout) catch |err| {
log.fatal(.app, "server run error", .{ .err = err });
return err;
};
Expand Down Expand Up @@ -773,7 +775,9 @@ fn serveCDP(address: std.net.Address, platform: *const Platform) !void {
defer app.deinit();

test_wg.finish();
server.run(app, address, std.time.ns_per_s * 2) catch |err| {
var server = try Server.init(app, address);
defer server.deinit();
server.run(address, 5) catch |err| {
std.debug.print("CDP server error: {}", .{err});
return err;
};
Expand Down
Loading