MCPcopy
hub / github.com/benoitc/gunicorn / AsyncUnreader

Class AsyncUnreader

gunicorn/asgi/unreader.py:14–135  ·  view source on GitHub ↗

Async socket reader with pushback buffer support. This class wraps an asyncio StreamReader and provides the ability to "unread" data back into a buffer for re-parsing. Performance optimization: Reuses BytesIO buffer with truncate/seek instead of creating new objects to reduce GC pr

Source from the content-addressed store, hash-verified

12
13
14class AsyncUnreader:
15 """Async socket reader with pushback buffer support.
16
17 This class wraps an asyncio StreamReader and provides the ability
18 to "unread" data back into a buffer for re-parsing.
19
20 Performance optimization: Reuses BytesIO buffer with truncate/seek
21 instead of creating new objects to reduce GC pressure.
22 """
23
24 def __init__(self, reader, max_chunk=8192):
25 """Initialize the async unreader.
26
27 Args:
28 reader: asyncio.StreamReader instance
29 max_chunk: Maximum bytes to read at once
30 """
31 self.reader = reader
32 self.buf = io.BytesIO()
33 self.max_chunk = max_chunk
34 self._buf_start = 0 # Start position of valid data in buffer
35
36 def _reset_buffer(self):
37 """Reset buffer for reuse instead of creating new BytesIO."""
38 self.buf.seek(0)
39 self.buf.truncate(0)
40 self._buf_start = 0
41
42 def _get_buffered_data(self):
43 """Get all buffered data and reset buffer."""
44 self.buf.seek(self._buf_start)
45 data = self.buf.read()
46 self._reset_buffer()
47 return data
48
49 def _buffer_size(self):
50 """Get size of buffered data."""
51 end = self.buf.seek(0, io.SEEK_END)
52 return end - self._buf_start
53
54 async def read(self, size=None):
55 """Read data from the stream, using buffered data first.
56
57 Args:
58 size: Number of bytes to read. If None, returns all buffered
59 data or reads a single chunk.
60
61 Returns:
62 bytes: Data read from buffer or stream
63 """
64 if size is not None and not isinstance(size, int):
65 raise TypeError("size parameter must be an int or long.")
66
67 if size is not None:
68 if size == 0:
69 return b""
70 if size < 0:
71 size = None

Callers 15

test_parse_simple_getFunction · 0.90
test_parse_headersFunction · 0.90
test_parse_https_schemeFunction · 0.90
test_read_body_chunksFunction · 0.90
test_drain_bodyFunction · 0.90
test_no_bodyFunction · 0.90

Calls

no outgoing calls

Tested by 15

test_parse_simple_getFunction · 0.72
test_parse_headersFunction · 0.72
test_parse_https_schemeFunction · 0.72
test_read_body_chunksFunction · 0.72
test_drain_bodyFunction · 0.72
test_no_bodyFunction · 0.72