Skip to content

Add (disabled) Speak Interleave test#102

Merged
xbhatnag merged 8 commits intomainfrom
echo
Feb 24, 2026
Merged

Add (disabled) Speak Interleave test#102
xbhatnag merged 8 commits intomainfrom
echo

Conversation

@xbhatnag
Copy link
Collaborator

@xbhatnag xbhatnag commented Feb 17, 2026

This test is the reverse of the echo test. When the client makes the request to the /speak endpoint, the server immediately starts writing 1-byte chunks to the client as the response body.

The server expects the client to “echo” each chunk back in the request body before it writes the next chunk.

The server sends 1000 “A” chunks and then the terminating chunk. The client will see the terminating chunk and also send the terminating chunk for the request body.

This test (and the Echo test) are disabled because URLSession has issues with bi-directional streaming support:

  • URLSession does not write 1-byte chunks out on the wire (occurs in speak and echo case)
  • URLSession hangs when the request outlives the response (occurs in speak case)

These tests do pass with other HTTP Client implementations.

No need to manually use a continuation with lock
This test is an inversion of the `echoInterleave()` test. When the client makes the request to the /speak endpoint, the server immediately starts writing 2-byte chunks to the client and expects the client to “echo” each chunk back to the server before continuing to the next chunk. The server sends 1000 “AB” chunks and then the terminating chunk. The client will see the terminating chunk and also end the request body.

This test is disabled because it does not work correctly with URLSession. The client does not process the terminating chunk from the server’s response body, so the request hangs at the end.
@xbhatnag xbhatnag added the 🔨 semver/patch No public API change. label Feb 17, 2026
A task is not necessary when we can write and read in lockstep in the server code.
Comment on lines 61 to 62
// TODO: URLSession client hangs when it receives the complete response body before it writes its complete request body.
// try await testSpeakInterleave()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should implement task cancellation here after 10sec and fail the test then. withTimeout(.seconds(10)) {}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried something like this, but it didn't seem to work.

withTimeout(..)
@available(macOS 26.2, iOS 26.2, watchOS 26.2, tvOS 26.2, visionOS 26.2, *)
public func withTimeout(seconds: Int, block: @Sendable @escaping () async throws -> Void) async throws {
    try await withThrowingTaskGroup { group in
        group.addTask {
            try await block()
        }
        group.addTask {
            do {
                try await Task.sleep(for: .seconds(seconds))
            } catch {
                // Ignore cancellation of the timer
            }
        }
        // Wait for either the task to complete or
        // for the timer to fire.
        try await group.next()

        // Cancel everything else.
        group.cancelAll()
    }
}

The timer does appear to fire, but cancellation of the task group doesn't unblock the test. I think the test is just uncooperative when it hangs?

LMK if I'm doing it wrong somehow.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is another big test case that we need! Cooperative task cancellation should unblock requests ASAP.

…ave test.

Now that we are using single-byte chunks for echo and speak tests, these tests will hang on URLSession, so we have kept them disabled for now.
@xbhatnag xbhatnag requested a review from guoye-zhang February 23, 2026 18:17
@xbhatnag xbhatnag enabled auto-merge (squash) February 24, 2026 15:35
@xbhatnag xbhatnag merged commit 79028be into main Feb 24, 2026
18 of 21 checks passed
@xbhatnag xbhatnag deleted the echo branch February 24, 2026 15:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔨 semver/patch No public API change.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants