properly flush frame after syncRequest eval

This commit is contained in:
Muki Kiboigo
2026-05-25 12:31:37 -07:00
parent 9ab82d2761
commit 673403f950
3 changed files with 49 additions and 13 deletions

View File

@@ -288,6 +288,9 @@ pub fn addFromElement(self: *ScriptManager, comptime from_parser: bool, script_e
return;
}
// This will flush any deferred scripts.
defer self.base.client.deferring_layer.flushFrame(self.base.owner.frameId());
if (script.status < 200 or script.status > 299) {
log.info(.http, "script load error", .{ .status = script.status });
script.executeCallback(comptime .wrap("error"));

View File

@@ -390,17 +390,6 @@ pub fn staticScriptsDone(self: *ScriptManagerBase) void {
lp.assert(self.static_scripts_done == false, "ScriptManagerBase.staticScriptsDone", .{});
self.static_scripts_done = true;
const frame_id = self.owner.frameId();
if (comptime IS_DEBUG) {
const blocking_request_id = self.client.blocking_requests.get(frame_id);
lp.assert(
blocking_request_id == null,
"there should be no blocking request on this frame",
.{ .value = blocking_request_id },
);
}
self.client.deferring_layer.flushFrame(frame_id);
self.evaluate();
}

View File

@@ -102,12 +102,17 @@ pub fn flushFrame(self: *DeferringLayer, frame_id: u32) void {
while (node) |n| {
node = n.next;
const ctx: *DeferredContext = @fieldParentPtr("node", n);
if (!ctx.deferring or !ctx.terminal) continue;
if (!ctx.deferring) continue;
const deferred_req = ctx.transfer.req;
if (deferred_req.frame_id == frame_id) {
if (deferred_req.frame_id != frame_id) continue;
if (ctx.terminal) {
self.active.remove(n);
ctx.fire();
} else {
ctx.firePartial();
ctx.deferring = false;
}
}
}
@@ -296,4 +301,43 @@ const DeferredContext = struct {
}
}
}
fn firePartial(self: *DeferredContext) void {
const req = self.transfer.req;
const stable_response = self.stable_resp orelse return;
const response = Response.fromStable(&stable_response);
for (self.buffered.items) |event| {
switch (event) {
.start => {
self.forward.forwardStart(response) catch |err| {
log.err(.http, "defer part start callback", .{ .err = err, .url = req.url });
self.forward.forwardErr(err);
return;
};
},
.header => {
const proceed = self.forward.forwardHeader(response) catch |err| {
log.err(.http, "defer part header callback", .{ .err = err, .url = req.url });
self.forward.forwardErr(err);
return;
};
if (!proceed) {
self.forward.forwardErr(error.Abort);
return;
}
},
.data => |chunk| {
self.forward.forwardData(response, chunk) catch |err| {
log.err(.http, "defer part data callback", .{ .err = err, .url = req.url });
self.forward.forwardErr(err);
return;
};
},
.done, .err, .shutdown => @panic("firePartial cant fire terminal events"),
}
}
self.buffered.clearRetainingCapacity();
}
};