Skip to content

chore: add backed reader, writer and pipe implementation #19147

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

ibetitsmike
Copy link
Contributor

@ibetitsmike ibetitsmike commented Aug 4, 2025

Fixes: #18101

This PR introduces a new backedpipe package that provides reliable bidirectional byte streams over unreliable network connections. The implementation includes:

  • BackedPipe: Orchestrates a reader and writer to provide transparent reconnection and data replay
  • BackedReader: Handles reading with automatic reconnection, blocking reads when disconnected
  • BackedWriter: Maintains a ring buffer of recent writes for replay during reconnection
  • RingBuffer: Efficient circular buffer implementation for storing data

The package enables resilient connections by tracking sequence numbers and replaying missed data after reconnection. It handles connection failures gracefully, automatically reconnecting and resuming data transfer from the appropriate point.

Copy link
Contributor Author

ibetitsmike commented Aug 4, 2025

@ibetitsmike ibetitsmike changed the title backed reader, writer and pipe implementation chore: add backed reader, writer and pipe implementation Aug 5, 2025
@ibetitsmike ibetitsmike force-pushed the mike/immortal-streams-backed-base branch from 9dd9c4a to 3223bf9 Compare August 5, 2025 08:46
@ibetitsmike ibetitsmike requested a review from spikecurtis August 5, 2025 09:36
@ibetitsmike ibetitsmike force-pushed the mike/immortal-streams-backed-base branch 2 times, most recently from d2ee08d to 27da7ef Compare August 7, 2025 11:18
@ibetitsmike ibetitsmike force-pushed the mike/immortal-streams-backed-base branch 3 times, most recently from 16abe05 to dde9516 Compare August 12, 2025 21:21
Copy link
Contributor

@spikecurtis spikecurtis left a comment

Choose a reason for hiding this comment

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

Not done with my review, but taking a break and wanted to send you comments so far.

Copy link
Contributor

@spikecurtis spikecurtis left a comment

Choose a reason for hiding this comment

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

Another batch of comments.

I haven't really looked at BackedPipe yet, but I think maybe it would be better to wait for the comments I've made so far to be resolved.

@ibetitsmike ibetitsmike force-pushed the mike/immortal-streams-backed-base branch from 7468299 to b2188f9 Compare August 15, 2025 00:51
@ibetitsmike ibetitsmike marked this pull request as ready for review August 15, 2025 08:50
if runtime.GOOS == "windows" {
// Don't run goleak on windows tests, they're super flaky right now.
// See: https://github.com/coder/coder/issues/8954
os.Exit(m.Run())
Copy link
Contributor

Choose a reason for hiding this comment

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

If Windows CLI tests are still flaky, then we need to look into it. That issue is closed not planned and has been for years.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Would it be possible for a test to leak on one os and not leak on another?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, especially on the CLI and Agent we need to do some OS specific shit around pseduo-TTYs. File I/O is different, so something might block indefinitely on one but not another OS. Stuff like that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I understand that and it sounds reasonable, but this test is conditioned only to execute goleak.VerifyTestMain(m, testutil.GoleakOptions...)

The rest of the testing logic of this package itself is not conditioned on the OS.

So my bottom line is - if we believe that goroutine leak detection flakes on Windows (and that condition is almost everywhere in the codebase ) - I wanted to stay consistent with that.

// Notify parent of error
select {
case bw.errorChan <- err:
default:
Copy link
Contributor

Choose a reason for hiding this comment

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

This has me worried. Dropping errors like this means that you might get a different number of error events depending on race conditions. How do we ensure we reconnect the correct number of times?

At the least, it needs a comment explaining why this works.

Since the reader and writer share the error channel, when the connection goes down you could get either 1 or 2 errors. Maybe one of the errors was swallowed by this branch, or maybe nothing was being written at the time, and so there was no error. If you get two errors, how do we know to reconnect only once?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The reconnect process is debounced by singleflight on the pipe level so I wouldn't expect them to trigger two reconnects.

However I've added separate channels for read & write errors in the backed pipe.

Is comment describing the behavior enough or do you feel there might be an edge case here I'm not testing for right now?

separate channels for writer/reader errors
moved to an interface for reconnection
coordination logic for closing a pipe
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Indestructible IDE Connections (No disconnects when you re-open laptop)
2 participants