Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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