refactor(fetch): Phase 4 - begin state machine integration

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 <noreply@anthropic.com>
This commit is contained in:
Claude Bot
2025-11-03 09:36:36 +00:00
parent 9715f88f2e
commit 27ff770bb8

View File

@@ -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;
}