Skip to content

feat(http): add native Ktor/Spring adapters and complete-response delivery - #54

Open
Sam Gammon (sgammon) wants to merge 4 commits into
mainfrom
feat/bali-framework-serving
Open

Sam Gammon (sgammon) wants to merge 4 commits into
mainfrom
feat/bali-framework-serving

Conversation

@sgammon

Copy link
Copy Markdown
Member

Change

Add optional Ktor and Spring WebFlux engines that use Bemo's native HTTP parser, encoder, sockets, and TLS. The shared Java loop consumes parsed request metadata and preserves framework routing/body codecs; it does not run a second HTTP wire parser.

For a small fixed response, the adapter now submits the headers and body in one native encode operation and receives one physical-transmission completion instead of streaming a head, body, and final part. Ktor also avoids constructing an unused cancellation exception after a channel has already closed.

The commits cover:

  • Direct Bali transport discovery with stock-JVM FFM fallback, compile-only guest API stubs, and panic containment at generated transport C exports.
  • Optional complete HTTP/1 response credit, with paired Rust/C/FFM/Native Image bindings and ownership tests.
  • A shared bounded HTTP loop, optional multiple workers, Ktor and Spring adapters, and framework build/package wiring.
  • Integration with current upstream static analysis, generated ABI documentation, and existing transport tests.

Metadata ABI 1 and transport ABI 3 remain unchanged. Complete-response support uses capability 4, preserving upstream native-allocation capability 2. The response flag is also 4, in its separate flag namespace. Older backends, larger bodies, unknown-length bodies, and streaming publishers retain the existing streaming path. Complete credit is rejected for HTTP/2 and when combined with streaming. Cancellation suppresses completion reports but retains wire buffers until native retirement; Response.sent() represents transmission or failure, not merely enqueueing.

Native HTTP remains opt-in. Ktor owner-local coroutine dispatch remains opt-in. HTTP/2/upgrades, general TLS policy/SNI/client-auth configuration, and graceful-drain qualification are outside this candidate; unsupported configuration is refused. See docs/http-frameworks.md.

Validation

Rebased onto 26fb123 (current main at preparation), preserving upstream allocator and transport fixes. macOS ARM64:

  • make test: 363 Rust tests, seven fuzz-corpus replay tests, and the JVM/FFM/C/transport contracts passed.
  • make test-native-image: passed, including HTTP complete/streaming response modes, worker lifecycle, and TLS.
  • Final make test-jvm and make test-native-image reruns after static-analysis cleanup: passed, run sequentially.
  • make test-miri: full configured scope passed.
  • make fuzz-smoke: 1,000 runs per configured target passed.
  • make fmt-check, Rust workspace/fuzz/embedder clippy, and Rust documentation checks: passed.
  • python3 tools/check_java.py: Error Prone/NullAway, Checker Framework, and analyzer-rejection fixtures passed.
  • python3 tools/test_git_dependency.py: external pinned Cargo consumer passed.
  • Generated-export, ABI-reference, and stock native-transport baseline checks passed.

make check remains blocked at cargo-deny by Rustls 0.23.45 advisories in upstream's unchanged Cargo.lock. No dependency/advisory suppression is included. The global hk commit hook also fails while evaluating the existing Pkl configuration (union property 'command' has no selected default); the checks above were invoked directly.

Earlier Bali performance evidence

These are diagnostic results from the pre-rebase integration candidate, not a benchmark of this rebased PR or a comparison against stock Java. Shared macOS host, HTTP/1.1, 64 connections, eight owners, matched explicit heap and original O2 compiler flags. Baseline/fixed/fixed/baseline, two fresh processes per variant; each process received 60 seconds warmup and three 10-second measurement windows. Values are medians of process medians. Zero errors across all windows.

Workload Baseline requests/s Fixed requests/s CPU/request p99
Ktor ping 100,301 142,814 81.25 → 55.66 µs 0.965 → 0.741 ms
Spring orders 61,999 71,836 140.25 → 123.84 µs 2.041 → 1.840 ms

A separate adapter-operation probe observed completion events 3 → 1 and chunk-prepare/chunk-send calls 2 → 0 each per fixed response; these are interface counts, not timing or C-call counts. The final Ktor profile contained zero fillInStackTrace samples in 1,600 HTTP-owner samples. Framework execution and guest/host transitions remain significant.

Linux, TLS performance, higher concurrency, and the full alternating stock-Java comparison matrix remain qualification work. No 10× claim or automatic default switch is made.

@codecov

codecov Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 71.67689% with 277 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.33%. Comparing base (26fb123) to head (6620d7a).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...ev/elide/bemo/transport/http/NativeHttpServer.java 69.72% 105 Missing and 103 partials ⚠️
crates/bemo-ffi/src/transport.rs 67.74% 50 Missing ⚠️
...elide/bemo/transport/TransportNativeDiscovery.java 47.61% 9 Missing and 2 partials ⚠️
...a/dev/elide/bemo/transport/FfmTransportNative.java 66.66% 2 Missing and 2 partials ⚠️
...ide/bemo/transport/FfmTransportNativeProvider.java 71.42% 2 Missing ⚠️
crates/bemo/src/abi/http.rs 97.05% 1 Missing ⚠️
...java/dev/elide/bemo/transport/TransportNative.java 50.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main      #54      +/-   ##
============================================
- Coverage     86.81%   86.33%   -0.49%     
- Complexity      616      717     +101     
============================================
  Files            60       64       +4     
  Lines         16979    17842     +863     
  Branches        490      669     +179     
============================================
+ Hits          14741    15403     +662     
- Misses         1914     2004      +90     
- Partials        324      435     +111     
Flag Coverage Δ
jvm 60.37% <68.99%> (+2.86%) ⬆️
rust 93.10% <79.51%> (+0.08%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@codspeed

codspeed Bot commented Oct 14, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 10.46%

⚠️ Unknown Walltime execution environment detected

Using the Walltime instrument on standard Hosted Runners will lead to inconsistent data.

For the most accurate results, we recommend using CodSpeed Macro Runners: bare-metal machines fine-tuned for performance measurement consistency.

⚠️ 6 benchmarks spent significant time in system calls

System calls cannot be consistently instrumented, so they are not included in the measure, which understates the real cost. Please switch to the Walltime instrument to accurately measure system calls.

Measurement and system calls

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 1 improved benchmark
❌ 4 regressed benchmarks
✅ 112 untouched benchmarks
⏩ 65 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
❌ Simulation retain-drop[1048576] 300.8 ns 354.9 ns -15.26%
❌ Simulation retain-drop[4096] 300.8 ns 354.9 ns -15.26%
❌ Simulation retain-drop[64] 300.8 ns 354.9 ns -15.26%
❌ Simulation retain-drop[65536] 300.8 ns 354.9 ns -15.26%
⚡ Simulation overwrite[64] 520.2 ns 466.1 ns +11.62%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing feat/bali-framework-serving (6620d7a) with main (26fb123)

Open in CodSpeed

Footnotes

  1. 65 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

This branch has not been deployed

No deployments
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.

1 participant