diff --git a/CHANGELOG.md b/CHANGELOG.md index 4af91af..c36da35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,25 @@ +## [0.16.0] - 2026-05-05 + +### 🚀 Features + +- Redefine HTTP status codes and add internal status header for error responses +- Optimize Wasmtime engine configuration for performance improvements +- Added `cache` crate with README and update dependencies +- Implemented `MemoryCacheBackend` with expiration and basic cache operations + +### 🐛 Bug Fixes + +- Update `fail_reason` type from `u32` to `i32` in stats for consistency + +### 🚜 Refactor + +- Change `fail_reason` type from `u32` to `i32`, migrate `MemoryCacheBackend` to use `tokio::Mutex` for async safety +- Remove unused tracing annotations from `CacheImpl` and update `README` for clarity + +### ⚙️ Miscellaneous Tasks + +- Update dependencies in Cargo.lock and Cargo.toml to latest versions +- Update Wasmtime dependency to use `component-model` feature ## [0.15.0] - 2026-03-10 ### 🚀 Features @@ -15,6 +37,10 @@ ### 📚 Documentation - Update usage guide for fastedge-run tool with detailed command options and examples + +### ⚙️ Miscellaneous Tasks + +- Release ## [0.14.0] - 2026-03-04 ### 🚀 Features diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..6ec9406 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,80 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Common commands + +```bash +# Build everything (CI uses --all-features) +cargo build --all-features + +# Run the full unit-test suite (CI command) +cargo test --all +cargo test -p # one crate, e.g. -p cache +cargo test -p http-service # one test by substring + +# Lint / format (CI runs both with -Dwarnings) +cargo fmt --all -- --check +cargo clippy --all-targets --all-features + +# Run the local CLI server against a wasm app +cargo run --bin fastedge-run -- http --port 8080 --wasm ./my_app.wasm +``` + +`RUSTFLAGS="-Dwarnings"` is the CI default — fix warnings before pushing. + +## Repository setup gotchas + +- **WIT is a git submodule.** `crates/reactor/wit/` is the `FastEdge-wit` repo. After clone or branch switches that touch it, run `git submodule update --init --recursive -f`. Without this, `crates/reactor` (and everything that depends on it) fails to build because `bindgen!` can't find the `.wit` files. +- **Custom Wasmtime fork.** All `wasmtime-*` deps point at `github.com/G-Core/wasmtime.git#release-36.0.0`. `.cargo/config.toml` contains a commented-out `[patch]` block that redirects those to a local sibling `../wasmtime` checkout — uncomment when developing against a local Wasmtime tree. +- **Wasm components vs core modules.** `componentize_if_necessary` (in `crates/runtime/src/lib.rs`) auto-wraps core modules using the bundled Preview1 adapter (`crates/runtime/src/adapters/wasi_snapshot_preview1.reactor.wasm`). Don't replace that adapter casually — it's pinned to the Wasmtime fork. + +## Architecture + +The workspace is a layered Wasm execution stack. Top to bottom: + +``` +src/ fastedge-run CLI binary (the only consumer of everything below) +crates/http-service/ Hyper server + per-request executor (HttpExecutorImpl, WasiHttpExecutorImpl) +crates/runtime/ Wasmtime engine, WasmConfig, Data store state, ProxyLimiter, pooling alloc +crates/reactor/ `bindgen!` of the FastEdge WIT world (host-trait surface for guests) +crates/http-backend/ Outbound HTTP client used by guest WASI-HTTP requests +crates/cache/ cache-sync host functions, CacheBackend trait +crates/key-value-store/ KV host functions (Redis-backed when feature `redis` is on) +crates/secret/ Secret variable host functions +crates/utils/ Dictionary host functions +``` + +### The host-state hub: `runtime::Data` + +Every Wasmtime `Store` holds a `Data` (in `crates/runtime/src/lib.rs`). It bundles **every** host capability the guest can call: `WasiCtx` (Preview1 *or* Preview2 — the `Wasi` enum), `WasiHttpCtx`, `WasiNnCtx`, `SecretStore`, `key_value_store::StoreImpl`, `Dictionary`, `Utils`, and `cache::CacheImpl`. `T` is whatever per-request payload the embedder threads through (e.g. `HttpState`). Adding a new host interface means: write the WIT, add a field to `Data`, register it in the linker in `runtime::WasmEngineBuilder`, and surface a constructor option on the appropriate trait (`ContextT` or `App`). + +### Two parallel WASI worlds + +`Data` supports both Preview 1 and Preview 2 via the `Wasi` enum and `WasiVersion`. `preview1_wasi_ctx_mut` / `preview2_wasi_ctx_mut` panic if called against the wrong variant — pick the variant via `StoreBuilder::new(engine, version)`. The CLI selects via the `--wasi-http` flag (Preview 2 path). + +### Executor selection + +`http-service` exposes two executors behind the same `HttpExecutor` trait: +- `HttpExecutorImpl` — the FastEdge `http-handler` WIT export. +- `WasiHttpExecutorImpl` — standard `wasi:http/incoming-handler`. + +`ExecutorFactory::get_executor` decides which one based on the `App` config / wasi_http flag. + +### Internal status codes + +5xx responses carry an `X-CDN-Internal-Status` header (3000–3999). The mapping (timeouts vs OOM vs trap kinds) is duplicated as `pub(crate) const`s in `crates/http-service/src/lib.rs` and as the table in README.md — keep both in sync when changing. + +### Plugging in a cache backend + +`cache::CacheBackend` is an `async_trait` (`Send + Sync`). `CacheImpl::new(Arc)` wraps it for the linker. The CLI ships `MemoryCacheBackend` (`src/cache.rs`) as the default; production embedders supply their own. `NoCacheBackend` returns `AccessDenied` for every op — use it as the deny-by-default fallback. + +## Crate features worth knowing + +- `runtime`: `kafka_log`, `victoria_log` (default on); `metrics` opts into Prometheus + lazy_static and propagates through `http-service/metrics`. +- `key-value-store`: `redis` enables the Redis-backed implementation. `runtime` already turns this on; if you depend on `key-value-store` from elsewhere, opt in explicitly. +- `cache`: no features yet — backend choice is at runtime via the `Arc` injected into `Data`. + +## Releasing + +GitFlow with `cargo-release` + `git-cliff`. The workflow lives in `release.toml` and `.github/workflows/release.yaml`; bump levels and the full procedure are in README.md. Don't hand-edit `CHANGELOG.md` — `git-cliff` regenerates it via the `pre-release-hook`. diff --git a/Cargo.lock b/Cargo.lock index 570455e..118498c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -265,7 +265,7 @@ checksum = "6bd91ee7b2422bcb158d90ef4d14f75ef67f340943fc4149891dcce8f8b972a3" [[package]] name = "cache" -version = "0.15.0" +version = "0.16.0" dependencies = [ "async-trait", "reactor", @@ -962,7 +962,7 @@ dependencies = [ [[package]] name = "fastedge-run" -version = "0.15.0" +version = "0.16.0" dependencies = [ "anyhow", "async-trait", @@ -1557,7 +1557,7 @@ dependencies = [ [[package]] name = "http-backend" -version = "0.15.0" +version = "0.16.0" dependencies = [ "anyhow", "claims", @@ -1600,7 +1600,7 @@ dependencies = [ [[package]] name = "http-service" -version = "0.15.0" +version = "0.16.0" dependencies = [ "anyhow", "async-trait", @@ -1959,7 +1959,7 @@ dependencies = [ [[package]] name = "key-value-store" -version = "0.15.0" +version = "0.16.0" dependencies = [ "async-trait", "reactor", @@ -2800,7 +2800,7 @@ dependencies = [ [[package]] name = "reactor" -version = "0.15.0" +version = "0.16.0" dependencies = [ "wasmtime", ] @@ -2920,7 +2920,7 @@ dependencies = [ [[package]] name = "runtime" -version = "0.15.0" +version = "0.16.0" dependencies = [ "anyhow", "async-trait", @@ -3089,7 +3089,7 @@ checksum = "0cd08a21f852bd2fe42e3b2a6c76a0db6a95a5b5bd29c0521dd0b30fa1712ec8" [[package]] name = "secret" -version = "0.15.0" +version = "0.16.0" dependencies = [ "anyhow", "reactor", @@ -3838,7 +3838,7 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "utils" -version = "0.15.0" +version = "0.16.0" dependencies = [ "reactor", ] diff --git a/Cargo.toml b/Cargo.toml index 6f1198c..497d461 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = ["crates/*"] resolver = "2" [workspace.package] -version = "0.15.0" +version = "0.16.0" edition = "2021" publish = false authors = ["FastEdge Development Team"] diff --git a/crates/reactor/wit b/crates/reactor/wit index ed3708a..de9bd0d 160000 --- a/crates/reactor/wit +++ b/crates/reactor/wit @@ -1 +1 @@ -Subproject commit ed3708a99b0bf0c4351a8287923bc0051da83b67 +Subproject commit de9bd0dc20a8f577f753aefa16b367a733a8511c