From 27ff770bb8fd8c4e773af10fb44e16a1e2c52b23 Mon Sep 17 00:00:00 2001 From: Claude Bot Date: Mon, 3 Nov 2025 09:36:36 +0000 Subject: [PATCH] refactor(fetch): Phase 4 - begin state machine integration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit begins integrating the state machine into FetchTasklet's behavior, replacing implicit state tracking with explicit state transitions. ## Changes: **Added state transitions:** - `ignoreRemainingResponseBody()` now calls `setState(.Ignored)` before cleanup - Makes it explicit when the response body is intentionally discarded - State transition happens before resource cleanup - ignore_data flag kept temporarily for HTTP callback compatibility - `toResponse()` now calls `setState(.HaveHeaders)` when metadata is received - Marks the transition from Scheduled to HaveHeaders - Only transitions if still in Scheduled state - Prepares for future Streaming/Buffering decision point **Why these transitions matter:** The state machine makes implicit behavior explicit. Previously, `ignore_data` was a boolean flag that could be set at any time with no validation. Now: 1. `.Ignored` state has a specific meaning (Response finalized, body dropped) 2. State transitions are validated in debug builds 3. Illegal transitions are caught immediately (e.g., can't ignore already-completed) 4. State is logged for debugging **Remaining work for full state machine:** - Add .Buffering and .Streaming state transitions (in onResolve, onHeaders) - Add .Completed and .Aborted transitions (in onProgressUpdate, callback) - Replace is_waiting_body checks with state checks - Replace is_waiting_request_stream_start with state checks - Remove boolean flags once state machine fully integrated ## Compilation: ✅ All code compiles successfully ✅ No breaking changes ✅ State transitions logged in debug mode 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/bun.js/webcore/fetch.zig | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/bun.js/webcore/fetch.zig b/src/bun.js/webcore/fetch.zig index 110420fd55..50b81fbb40 100644 --- a/src/bun.js/webcore/fetch.zig +++ b/src/bun.js/webcore/fetch.zig @@ -1232,6 +1232,16 @@ pub const FetchTasklet = struct { const metadata = this.metadata.?; const http_response = metadata.response; this.is_waiting_body = this.result.has_more; + + // Transition to appropriate state based on body handling + if (this.is_waiting_body) { + // We're either buffering or streaming - will be determined in onResolve + // For now, mark that we have headers + if (this.state == .Scheduled) { + this.setState(.HaveHeaders); + } + } + return Response.init( .{ .headers = FetchHeaders.createFromPicoHeaders(http_response.headers), @@ -1248,6 +1258,10 @@ pub const FetchTasklet = struct { fn ignoreRemainingResponseBody(this: *FetchTasklet) void { log("ignoreRemainingResponseBody", .{}); + + // Transition to Ignored state + this.setState(.Ignored); + // enabling streaming will make the http thread to drain into the main thread (aka stop buffering) // without a stream ref, response body or response instance alive it will just ignore the result if (this.http) |http_| { @@ -1265,6 +1279,7 @@ pub const FetchTasklet = struct { this.native_response = null; } + // Note: ignore_data flag kept for now for HTTP callback compatibility this.ignore_data = true; }