SetReadDeadline behavior
Closed this issue · 1 comments
Context
I am developing a QUIC client that establishes a connection and opens a single SendStream
. This client continually sends packets with high frequency into this stream over an extended period:
// QUIC Client
func (c *QUICClient) write(msg []byte) error {
// This is a stream from `OpenUniStreamSync`
err := c.stream.SetWriteDeadline(time.Now().Add(c.writeTimeout))
if err != nil {
loggerClient.Error("Failed to set write deadline", "err", err)
return ErrOpenStream
}
_, err = c.stream.Write(msg)
if err != nil {
loggerClient.Error("Failed to write to stream", "err", err)
return ErrSendPatch
}
return nil
}
On the server side, I handle this stream to process packets over time, with the goal of keeping the stream open for a prolonged period:
// QUIC Server
func (s *Server) handleStream(
ctx context.Context,
stream quicgo.ReceiveStream,
conn quicgo.Connection,
) {
for {
err := stream.SetReadDeadline(time.Now().Add(ReadTimeout))
if err != nil {
slog.Error("Failed to set read deadline for QUIC stream", "err", err)
}
// Read the patch length
lengthBuffer := make([]byte, PatchLengthPrefix)
_, err = io.ReadFull(stream, lengthBuffer)
if err != nil {
slog.Error("Failed to QUIC read patch length", "err", err)
return
}
patchLength := binary.BigEndian.Uint32(lengthBuffer)
slog.Info("Got patch length", "length", patchLength)
// Read the whole patch
buffer := make([]byte, patchLength)
_, err = io.ReadFull(stream, buffer)
if err != nil {
slog.Error("Failed to read complete QUIC patch", "err", err)
return
}
// Handle the patch
go func(patch []byte) {
err := s.handlePatch(ctx, conn, patch)
if err != nil {
slog.Error("Error handling QUIC patch", "err", err)
return
}
slog.Info("Successfully handled QUIC patch from client")
}(buffer)
}
}
Question
How does SetReadDeadline
behave in this case? Specifically:
- When a packet arrives, does
SetReadDeadline
allow reading from it for the entireReadTimeout
duration, after which it checks for new packets if the current one was unreadable in that time frame? - Alternatively, does
SetReadDeadline
simply wait for a packet for up toReadTimeout
and time out if none arrives?
I'm uncertain how to configure SetReadDeadline
on the server side to ensure the server continues processing incoming packets within an open SendStream
over an extended time.
I expected:
- The server can process packets over a long duration on a single open
SendStream
from the client. - The
SetReadDeadline
only times out when absolutely no packets have been received withinReadTimeout
- not if a packet takes slightly longer to be fully read.
P.S Big thanks for building this library and being so helpful! ❤
Deadlines behave exactly as they do in the Go standard library. They're purely a local operation to make calls to Read
and Write
return once the deadline is reached.