fix: #254 bound receiver queue by aggregate payload bytes
The per-connection memory budget (MAX_CONNECTION_MEMORY, 256 MiB) only charged wire buffers via receive_data_limited. Decompression buffers and per-file chunk copies were not accounted for, and the multithreaded receiver could enqueue up to 100 files (each up to 64 MiB uncompressed) ahead of a slow disk writer, retaining ~6.4 GiB per connection. A client sending highly compressible chunks with little bandwidth could OOM the host while the reserve never tripped. Bound the receive pipeline by aggregate payload bytes instead of item count alone: - Export MAX_CONNECTION_MEMORY from protocol.h. - PipelineContextReceiver tracks queued_bytes (payload bytes received but not yet released by the disk writer, i.e. queued or in the writer's hand) under the existing mutex. - receiver enqueue now blocks while the queue is full by count OR when adding the file would push queued_bytes over the configured byte limit, applying backpressure to the sender instead of failing the transfer. - The disk writer releases the byte budget after each file is freed and signals the not-full condition. - The server sets the byte ceiling to MAX_CONNECTION_MEMORY - 2*MAX_CHUNK_SIZE so that the queued payloads plus the transient wire/decompression buffers of the one in-flight chunk stay within the per-connection budget. The single-threaded receive path is already bounded: it writes files to disk before reading the next chunk, so its transient is at most one chunk's wire + decompressed + copied payload (~3 * MAX_CHUNK_SIZE, below the budget). Wire buffers remain charged exactly once by receive_data_limited; this change does not double charge them. Adds a deterministic unit test in test_multiprocessing.c proving that an enqueue which would exceed the byte budget blocks until the writer releases bytes.
This commit is contained in:
@@ -22,6 +22,10 @@
|
||||
#define DEFAULT_MAX_ALLOC (1ULL * 1024 * 1024 * 1024)
|
||||
/* Server policy ceiling for a client-provided allocation limit. */
|
||||
#define MAX_SERVER_ALLOC (256ULL * 1024 * 1024)
|
||||
/* Bounded cumulative per-connection receive budget. In-flight wire buffers,
|
||||
decompression buffers and queued (not yet written) file payloads for a
|
||||
connection must stay within this ceiling. */
|
||||
#define MAX_CONNECTION_MEMORY (256ULL * 1024 * 1024)
|
||||
|
||||
typedef struct ssl_st SSL;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user