-
Notifications
You must be signed in to change notification settings - Fork 1
feat: per-request interpreter architecture (DD-006) #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
larimonious
wants to merge
11
commits into
main
Choose a base branch
from
feat/http-server-refactor
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
5728788
feat: Value::FlatFunction, StoredHandler, flatten_value() — DD-006 Ph…
larimonious 065c9a0
feat: extract SharedState with type context — DD-006 Phase 3
larimonious f83a609
feat: per-request execution engine, execute_request(), spawn_blocking…
larimonious 05ed172
docs: migration guide, new env vars, architecture update — DD-006 Pha…
larimonious 81f8bf0
refactor: delete http_bridge, remove sync server, per-request always …
larimonious a1b088c
feat: wire test_mode shutdown flag to async server, remove partial Ph…
larimonious c0591b2
feat: hot-reload atomic swap, intent check/studio → execute_request —…
larimonious f8448e6
test: DB connection across per-request boundary — DD-006 Phase 4 DoD
larimonious c0251dc
bench: criterion + wrk benchmarks — DD-006 performance results
larimonious 5d473a8
perf: thread-local interpreter pool, reset_for_reuse — DD-006
larimonious 7f0eecb
fix: reset_for_reuse — fresh env root, clear loaded_modules — DD-006 …
larimonious File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -42,9 +42,9 @@ src/ | |||||||
| ├── crypto.rs # std/crypto - SHA256, HMAC, UUID, random | ||||||||
| ├── url.rs # std/url - URL encoding/parsing | ||||||||
| ├── http.rs # std/http - HTTP client (fetch, download) | ||||||||
| ├── http_server.rs # std/http/server - Response builders | ||||||||
| ├── http_server_async.rs # Async HTTP server (Axum + Tokio) | ||||||||
| ├── http_bridge.rs # Bridge between async server and sync interpreter | ||||||||
| ├── http_server.rs # std/http/server - Route registration, SharedState, StoredHandler, response builders | ||||||||
| ├── http_server_async.rs # Axum server, per-request execution, hot-reload watcher | ||||||||
| ├── http_bridge.rs # Send-safe HTTP types (BridgeRequest/BridgeResponse) | ||||||||
| ├── template.rs # External template loading | ||||||||
| ├── postgres.rs # std/db/postgres - PostgreSQL client | ||||||||
| └── concurrent.rs # std/concurrent - Channels, sleep | ||||||||
|
|
@@ -112,34 +112,57 @@ Runtime contract checking: | |||||||
|
|
||||||||
| ## HTTP Server Architecture | ||||||||
|
|
||||||||
| The HTTP server uses a bridge pattern to connect async Axum handlers to the synchronous interpreter: | ||||||||
| The HTTP server uses a **per-request interpreter** model for true parallel request handling: | ||||||||
|
|
||||||||
| ``` | ||||||||
| ┌─────────────────────────────────────────────────────────────────┐ | ||||||||
| │ Tokio Async Runtime │ | ||||||||
| │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ | ||||||||
| │ │ Task 1 │ │ Task 2 │ │ Task N │ (async handlers) │ | ||||||||
| │ └────┬────┘ └────┬────┘ └────┬────┘ │ | ||||||||
| │ └────────────┼────────────┘ │ | ||||||||
| │ │ │ | ||||||||
| │ ┌─────▼─────┐ │ | ||||||||
| │ │ Channel │ (mpsc + oneshot reply) │ | ||||||||
| │ └─────┬─────┘ │ | ||||||||
| └────────────────────┼────────────────────────────────────────────┘ | ||||||||
| │ | ||||||||
| ┌────────────────────▼────────────────────────────────────────────┐ | ||||||||
| │ Interpreter Thread │ | ||||||||
| │ - Receives requests via channel │ | ||||||||
| │ - Finds and calls NTNT handler function │ | ||||||||
| │ - Sends response back via oneshot channel │ | ||||||||
| │ - Uses Rc<RefCell<>> (not thread-safe, hence single thread) │ | ||||||||
| └─────────────────────────────────────────────────────────────────┘ | ||||||||
| Startup phase: | ||||||||
| Parse .tnt files → register routes/middleware → snapshot closures into SharedState | ||||||||
| Wrap SharedState in Arc<RwLock<SharedState>> | ||||||||
|
|
||||||||
| Request phase (fully parallel): | ||||||||
| ┌─────────────────────────────────────────────────────────────────┐ | ||||||||
| │ Tokio Async Runtime (Axum) │ | ||||||||
| │ │ | ||||||||
| │ Request 1 → route lookup → spawn_blocking → Interpreter → Resp│ | ||||||||
| │ Request 2 → route lookup → spawn_blocking → Interpreter → Resp│ | ||||||||
| │ Request N → route lookup → spawn_blocking → Interpreter → Resp│ | ||||||||
| │ │ | ||||||||
| │ Static files → Axum/tower-http directly (no interpreter) │ | ||||||||
| └─────────────────────────────────────────────────────────────────┘ | ||||||||
| ``` | ||||||||
|
|
||||||||
| Each request gets its own `Interpreter` instance with its own `Environment` chain. No locks during execution, no channels, no contention. The interpreter uses `Rc<RefCell<>>` internally (not thread-safe), but this is safe because each instance is confined to a single `spawn_blocking` task. | ||||||||
|
|
||||||||
| ### SharedState | ||||||||
|
|
||||||||
| Route handlers are stored as `StoredHandler` — a `Send`-safe representation that snapshots the handler's closure environment at registration time, converting all `Value::Function` instances to `Value::FlatFunction` (no `Rc`). At request time, `StoredHandler::to_call_value()` reconstitutes a live `Value::Function` with a fresh `Rc<RefCell<Environment>>`. | ||||||||
|
|
||||||||
| `SharedState` also carries type context (`structs`, `enums`, `type_aliases`, `trait_definitions`, `trait_implementations`) so per-request interpreters can use user-defined types. | ||||||||
|
|
||||||||
| ### Hot-Reload | ||||||||
|
|
||||||||
| A background async task polls for file changes at `NTNT_HOT_RELOAD_INTERVAL_MS` (default: 500ms). On change, `rebuild_shared_state()` creates a fresh interpreter, re-parses all .tnt files, and atomically swaps the `Arc<RwLock<SharedState>>`. In-flight requests complete with the old state; new requests use the new state. Zero dropped requests. | ||||||||
|
|
||||||||
| ### Key Environment Variables | ||||||||
|
|
||||||||
| | Variable | Default | Description | | ||||||||
| |----------|---------|-------------| | ||||||||
| | `NTNT_BLOCKING_THREADS` | Tokio default (~512) | `spawn_blocking` thread pool size | | ||||||||
| | `NTNT_REQUEST_TIMEOUT` | 30s | Max handler execution time (504 on breach) | | ||||||||
| | `NTNT_HOT_RELOAD_INTERVAL_MS` | 500ms | File watcher poll interval (dev mode only) | | ||||||||
|
|
||||||||
| ### Performance | ||||||||
|
|
||||||||
| Interpreter construction: **43.9 µs** (full construction + 23 stdlib modules, release build). This enables ~22K constructions/sec per core. Static files bypass the interpreter entirely. | ||||||||
|
|
||||||||
| ### Behavioral Change: Module-Level Mutable State | ||||||||
|
|
||||||||
| Module-level mutable state is snapshotted at registration time. Each request starts from that snapshot — mutations in one request are not visible to others. Use `kv_set`/`kv_get` (Redis) for cross-request state. | ||||||||
|
|
||||||||
| **Key files:** | ||||||||
| - `http_server_async.rs` - Axum server setup, async handlers, static files | ||||||||
| - `http_bridge.rs` - Request/response types, channel communication | ||||||||
| - `http_server.rs` - Response builders (`json()`, `html()`, etc.) | ||||||||
| - `http_server.rs` - Route registration, `SharedState`, `StoredHandler`, response builders, stdlib HTTP functions | ||||||||
| - `http_server_async.rs` - Axum runner, `execute_request()`, static files, graceful shutdown, hot-reload watcher | ||||||||
| - `http_bridge.rs` - Bridge types (`BridgeRequest`/`BridgeResponse`) for `Send`-safe HTTP representation | ||||||||
|
Comment on lines
+164
to
+165
|
||||||||
| - `http_server_async.rs` - Axum runner, `execute_request()`, static files, graceful shutdown, hot-reload watcher | |
| - `http_bridge.rs` - Bridge types (`BridgeRequest`/`BridgeResponse`) for `Send`-safe HTTP representation | |
| - `http_server_async.rs` - Axum runner, `execute_request()`, bridge types (`BridgeRequest`/`BridgeResponse`) for `Send`-safe HTTP representation, static files, graceful shutdown, hot-reload watcher |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ARCHITECTURE.mdstill listsstdlib/http_bridge.rs, but that file is removed in this PR andBridgeRequest/BridgeResponsenow live inhttp_server_async.rs. Update the source tree and “Key files” sections to reflect the current file layout (or re-add a dedicated module if that’s the intent).