1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
//! `cratefield-runtime-native` runs a Factory Zero `Harness` as a single
//! binary on tokio (ADR 0001, issue #19): axum on a `TcpListener`,
//! `reqwest` (rustls) behind the `HttpClient` port, Redis behind
//! `RateLimiter` and `KeyValue`, `tokio::spawn` behind `Defer`, the
//! system clock behind `Clock`, and an in-process cron scheduler fanning
//! out to every module's `scheduled(ctx, cron)`.
//!
//! The move for a venture (architecture section 10): keep the modules and
//! adapters, switch `.runtime(Cloudflare::new().db("DB"))` for
//! `.runtime(Native::new().db(Postgres::connect(url).await?))`, ship the
//! Dockerfile. No module code changes.
//!
//! # Native-only gate
//!
//! tokio, reqwest, redis and the JSON log subscriber do not compile to
//! wasm, so this crate is impossible to build for a wasm target:
//! `src/lib.rs` fails compilation with a clear message on `wasm32`/
//! `wasm64` (the same gate `cratefield-adapter-postgres` uses), and the
//! native dependencies are target-gated in `Cargo.toml`. The wasm graph
//! of `examples/venture` must stay free of this crate; CI asserts it
//! with `cargo tree --target wasm32-unknown-unknown`.
//!
//! # Client IP (the one behavioral difference from Workers)
//!
//! On Workers the edge sets `cf-connecting-ip` and forwarding headers are
//! client-forgeable. A native deployment sits behind its **own** proxy,
//! so this runtime owns IP resolution: [`trusted_proxy_headers`] lists
//! the header names the deployment is willing to believe (default
//! **empty** — an unconfigured deployment trusts no forwarding header),
//! [`client_ip`] resolves the address from those headers or the socket
//! peer, and the server middleware sanitizes every forwarding header
//! before the router sees the request. See [`client_ip`] for how the
//! resolved address is carried to the modules.
//!
//! # Redis is not the Workers bindings
//!
//! [`RedisRateLimiter`] and [`RedisKv`] implement the ports with
//! semantics as close to the Workers Rate Limiting binding and KV as
//! Redis allows; every difference is documented on the type, not papered
//! over. The headline ones: the limiter is a true sliding window that
//! can report `retry_after` (the binding is fixed-window and cannot),
//! and Redis is strongly consistent and single-node where KV is
//! eventually consistent and replicated per-colo.
//!
//! ```ignore
//! # async fn demo() -> Result<(), Box<dyn std::error::Error>> {
//! use std::sync::Arc;
//! use cratefield_core::Harness;
//! use cratefield_runtime_native::{Native, serve};
//!
//! let db = cratefield_adapter_postgres::Postgres::connect("postgres://user:pass@host:5432/venture").await?;
//! let harness = Arc::new(harness()); // your composition, as on Workers
//! let runtime = Native::new().db_arc(Arc::new(db));
//! serve(harness, runtime).await?;
//! # Ok(())
//! # }
//! # fn harness() -> Harness { unimplemented!() }
//! ```
// The whole crate is native-only (issue #19). Modules see ports, never
// runtimes, so no wasm graph reaches this crate through a module; the
// hazard is a venture that wires the wrong runtime into a Worker.
//
// **This message has never been printed, and cannot be.** Cargo builds a
// crate's dependencies before the crate itself, so a wasm build of this
// one dies in mio — "This wasm target is unsupported by mio" — long
// before this line is evaluated. A `build.rs` does not rescue it either;
// cargo aborts on the dependency failure first. The guard stays because
// it documents the rule at the place the rule is about, but the check
// that actually runs is `no_wasm_package_can_reach_a_native_only_crate`
// in `crates/cli-acceptance/tests/native_only_off_wasm.rs`, which reads
// the dependency graph instead of compiling it — and which finds this
// crate *by* the guard below, so deleting it turns that check off.
compile_error!;
pub use EnvConfig;
pub use ;
pub use ;
pub use Native;
pub use ;
pub use install_tracing;