Skip to content

Feat: HTTP worker cancellation upon client closing connection, fix for large orchestration jobs failing to run and compression inprovements - #44

Merged
Zacgoose merged 6 commits into
mainfrom
dev
Sep 24, 2026
Merged

Zacgoose merged 6 commits into
mainfrom
dev

Conversation

@Zacgoose

Copy link
Copy Markdown
Contributor

This pull request introduces two main improvements: (1) enhanced handling of HTTP client disconnects and request cancellation in the PowerShell dispatch pipeline, and (2) robust support for large entity splitting and reassembly in the Azure Table storage layer. These changes improve reliability, correctness, and efficiency for both HTTP endpoint execution and storage of large logical entities.

HTTP Request Cancellation and Reliability Improvements:

  • HTTP endpoints now properly honor client disconnects for read (GET) requests by linking the HTTP cancellation token to the PowerShell execution pipeline, ensuring that resources are freed promptly and partial results are never cached or returned if the client aborts. Write requests (POST/PUT/DELETE/PATCH) always run to completion, even if the client disconnects, to avoid partial mutations. [1] [2] [3] [4] [5] [6] [7]

Azure Table Storage: Large Entity Splitting, Reassembly, and Cleanup:

  • The storage layer now transparently splits large logical entities across multiple physical rows when necessary, and reassembles them on read. This includes logic to clean up "part" rows left behind by previous larger versions or deletes, preventing stale data from being returned on future reads. [1] [2] [3] [4] [5] [6] [7] [8] [9]
  • Batch upserts and conditional replacements now handle splitting and cleanup atomically, ensuring that logical operations remain all-or-nothing even when entities are split. The batch size cap is enforced after splitting to avoid partial application. [1] [2]
  • Partition and table scans now yield fully reassembled entities, except for projected queries which intentionally skip reassembly to expose all physical rows for maintenance operations. [1] [2]
  • Deletes now also remove any associated "part" rows to prevent deleted entities from being accidentally reconstructed during partition scans.

Link HTTP request cancellation to PowerShell execution so client disconnects stop the pipeline promptly. Return a 499-style result for aborted requests, skip cache/response writes for partial output, and still invalidate write caches because a non-GET operation may have already applied.
Store oversized table entities across multiple properties and rows, then reassemble them on read so task parameters and other payloads no longer fail Azure Table size limits. This includes stale part cleanup, conditional-write safety, and regression tests covering large payloads, batch writes, deletes, and orchestrator task rehydration.
String bodies (Response.WriteAsync) and CraftResult.Stream writers reach the
encoder through the response pipe, one ~4 KiB segment per write. Brotli's
fast qualities compress each write as an isolated fragment, and every encoder
pays per-call overhead. Both providers now sit behind a 64 KiB BufferedStream:
output still streams every 64 KiB and flushes pass straight through.

Real 300 KB ListLogs body: br Fastest 85 KB -> 36 KB and 2.5x faster; br
Optimal (the default) ~10-20% less CPU with identical bytes; gzip unchanged.
Providers are now constructed with their level instead of via IOptions.

Tests: per-encoding negotiation and round-trip, br winning a browser-style
Accept-Encoding, and a real-Kestrel check that a varied string body is not fed
to the encoder as fragments (fails without the coalescing).

Harness: PerfFile serves a captured real response verbatim from PAYLOAD_DIR;
run-compression-levels.ps1 gains -Url/-PayloadDir, p50, and a discarded
warm-up pass so the first-measured encoding no longer absorbs JIT and pool
growth.
.NET 8 on Linux does gzip through the system libz.so.1. Stage zlib-ng 2.3.3
(zlib-compat build, pinned + sha256-verified, runtime CPU dispatch) and copy
it onto the runtime's libz.so.1, the same way mimalloc is staged.

Azure Linux runtime, 2 vCPU, default level (Optimal = zlib 6):
- 10 MB ListLogs body: 165 -> 84 ms per encode, 3.8% smaller on the wire
- under load (3 rps of 10 MB): gzip CPU over identity ~60 -> ~37 points
- 32 KB: 296 -> 187 us; <= 2 KB unchanged
Every case round-trips byte-identical. Brotli is unaffected.
@Zacgoose Zacgoose changed the title Feat: HTTP worker cancellation upon client closing connection, fix for large orchestration jobs failing to run Feat: HTTP worker cancellation upon client closing connection, fix for large orchestration jobs failing to run and compression inprovements Sep 23, 2026
@Zacgoose
Zacgoose merged commit 5b08682 into main Sep 24, 2026
7 checks passed
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.

2 participants