handle timeouted h2 connections, refill reply budget

This commit is contained in:
Flowseal committed 2026-10-10 21:36:28 +03:00
1 parent 59c3a6e3b3
commit 3cda0f5446
4 files changed
+95 -4

No files matched your search

+5 -1
View File
@@ -98,10 +98,11 @@ class _ReplayPacket:
pending: Optional[asyncio.Task] = None
originals: Set[asyncio.Task] = field(default_factory=set, repr=False)
retired: bool = False
reply_id: Optional[bytes] = None
@property
def replayed(self) -> bool:
return self.attempts > 0
return self.last_attempt_at > 0 or self.attempts > 0
async def _read_packet(reader, decryptor, tag: bytes) -> Tuple[bytes, bool]:
@@ -466,6 +467,9 @@ class _HttpChannel:
reply = await self.lane._post(body, self.channel_id, replay=replay, channel=self)
self.last_progress = time.monotonic()
if reply and not self.closed:
if packet is not None and reply[:24] != packet.reply_id:
packet.reply_id = reply[:24]
packet.attempts = 0
if self.queue.full() or self.reply_bytes + len(reply) > MAX_CHANNEL_BYTES:
raise BufferError('H2 client response queue exceeded bound')
self.reply_bytes += len(reply)
+8 -1
View File
@@ -49,7 +49,14 @@ class _ResponseStream(httpx.AsyncByteStream):
try:
await asyncio.wait_for(self.changed.wait(), self.read_timeout)
except asyncio.TimeoutError as exc:
raise httpx.ReadTimeout('Timed out waiting for H2 stream %d' % self.stream_id) from exc
error = httpx.ReadTimeout('Timed out waiting for H2 stream %d' % self.stream_id)
# An idle socket can remain established after the path stops
# delivering data. Reconnect once its last active request times
# out, while preserving unrelated requests and buffered replies.
if not any(stream is not self and not stream.ended
for stream in self.connection.streams.values()):
self.connection.fail(error)
raise error from exc
def check_error(self):
if self.error is not None: