Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
172 commits
Select commit Hold shift + click to select a range
cf16418
Add request phase timing design spec and implementation plan (#1069)
jevansnyc Aug 25, 2026
052eada
Add RequestTimings phase collection and Server-Timing rendering
jevansnyc Aug 25, 2026
7505fb8
Add observability settings and decouple tinybird access and auction e…
jevansnyc Aug 25, 2026
4ce413f
Add test coverage for the access_enabled without tinybird.enabled rej…
jevansnyc Aug 25, 2026
f83092a
Emit Server-Timing at the send freeze point on conclusively private r…
jevansnyc Aug 25, 2026
4b19c44
Record filter and geo spans and dedupe the per-request geo lookup
jevansnyc Aug 25, 2026
ce295f1
Record origin, template cache, and KV phase spans in core
jevansnyc Aug 25, 2026
c222ae2
Capture stream duration, auction wait placement, and response bytes
jevansnyc Aug 25, 2026
8b028bb
Add access telemetry snapshot, route classes, and coarse route templates
jevansnyc Aug 25, 2026
48acd81
Emit confirmed access telemetry rows after pull-sync post-send
jevansnyc Aug 25, 2026
72d5755
Extend access_logs_raw with phase columns and a non-null sorting key
jevansnyc Aug 25, 2026
c50be03
Widen time_elapsed_ms to nullable so dropped snapshots cannot quarant…
jevansnyc Aug 25, 2026
0aead79
Emit Server-Timing from the Axum terminal layer with adapter-specific…
jevansnyc Aug 25, 2026
e9cf5b9
Document the observability and access telemetry configuration surface
jevansnyc Aug 25, 2026
7942c74
Normalize telemetry method, guard zero sample rate, and mirror geo wr…
jevansnyc Aug 26, 2026
d8fcb5e
Add a local dev config envelope generator example
jevansnyc Aug 26, 2026
7cf7d86
Add JSONPaths and expression sorting key to the access datasource
jevansnyc Aug 26, 2026
600746f
Use web_time Instant on request timing paths
jevansnyc Aug 26, 2026
3d7e697
Reject opaque identifier segments in publisher route templates
jevansnyc Aug 26, 2026
38043d7
Address access telemetry review feedback
jevansnyc Aug 26, 2026
274241b
Add auction timeline offsets spec amendment
jevansnyc Aug 26, 2026
29d45e8
Add auction timeline offsets implementation plan
jevansnyc Aug 26, 2026
46911a6
Record T0-anchored auction timeline offsets in the access row
jevansnyc Aug 26, 2026
1fa9f8c
Remove generated integration wrangler config from tracking
jevansnyc Aug 26, 2026
2ef7635
Reject single-segment publisher paths in route templates
jevansnyc Aug 28, 2026
082461d
Sample access rows with real randomness at the snapshot rate
jevansnyc Aug 28, 2026
f3ee473
Drop the origin span before error-path auction telemetry
jevansnyc Aug 28, 2026
46b3c7f
Address remaining review feedback on timing surfaces and docs
jevansnyc Aug 28, 2026
a0a3af5
Merge remote-tracking branch 'origin/main' into feat/request-phase-ti…
ChristianPavilonis Aug 31, 2026
c6235b9
Enforce access telemetry body limit
ChristianPavilonis Aug 31, 2026
fde55b1
docs: design mobile ad-render trace endpoint
prk-Jr Sep 1, 2026
8899dca
docs: harden mobile ad trace design
prk-Jr Sep 1, 2026
534a691
Add server auction evidence to mobile trace design
prk-Jr Sep 1, 2026
dc34278
Report a reason when an APS creative render fails
jevansnyc Aug 20, 2026
fae9e35
Attribute APS creative delivery in GPT diagnostics
jevansnyc Aug 20, 2026
576ef33
Merge remote-tracking branch 'origin/feat/request-phase-timing' into …
ChristianPavilonis Sep 4, 2026
ca46e4f
Format auction timeline implementation plan
ChristianPavilonis Sep 4, 2026
4d3e02d
Merge branch 'main' into aps-renderer-failure-diagnostics
aram356 Sep 7, 2026
c59611e
Persist the tester cookie for 30 days so it survives browser restarts
jevansnyc Sep 7, 2026
6f133cc
Merge origin/main into feat/request-phase-timing
jevansnyc Sep 8, 2026
bcc1475
Bound route templates by allowlist and harden the telemetry config su…
jevansnyc Sep 8, 2026
a152367
Address round-3 telemetry robustness findings
jevansnyc Sep 8, 2026
6b36f92
Merge branch 'main' into aps-renderer-failure-diagnostics
aram356 Sep 8, 2026
3c1b2dd
Merge branch 'main' into worktree-tester-cookie-max-age
aram356 Sep 10, 2026
0c390c3
Merge branch 'main' into aps-renderer-failure-diagnostics
aram356 Sep 10, 2026
20debdf
Merge branch 'main' into spec/mobile-ad-render-trace-endpoint
prk-Jr Sep 10, 2026
b9c6862
Merge branch 'main' into worktree-tester-cookie-max-age
aram356 Sep 11, 2026
282d78b
Merge branch 'main' into spec/mobile-ad-render-trace-endpoint
prk-Jr Sep 14, 2026
285e003
Merge branch 'main' into aps-renderer-failure-diagnostics
aram356 Sep 14, 2026
1476137
Show help for a bare ts dev proxy invocation
dhruv8sh Sep 15, 2026
ecc962f
Enforce formatting on root level markdown files
dhruv8sh Sep 15, 2026
ed813cb
Add CI gate to AGENTS checklist
dhruv8sh Sep 15, 2026
ae1d7c6
Address PR review: preserve CA error attachments, fix test process-ex…
dhruv8sh Sep 15, 2026
85ac1ff
Move test-only clap import to module scope, harden second parse trap
dhruv8sh Sep 15, 2026
96619de
Reject placeholder partner pull tokens on startup
dhruv8sh Sep 16, 2026
9e7b96f
Merge branch 'main' into fix/reject-placeholder-partner-pull-tokens
dhruv8sh Sep 16, 2026
98247d6
Document EdgeZero store selector alignment
aram356 Sep 16, 2026
ca5b4d4
Plan EdgeZero store selector alignment
aram356 Sep 16, 2026
fbeb195
Use canonical Fastly secret store selectors
aram356 Sep 16, 2026
f2b1b39
Consume canonical EdgeZero deployment selectors
aram356 Sep 16, 2026
3416b71
Document deploy-time Fastly store selection
aram356 Sep 16, 2026
afba58b
Merge branch 'main' into fix/dev-proxy-bare-invocation-help
dhruv8sh Sep 16, 2026
589a6cd
Merge branch 'main' into chore/check-root-markdown-formatting
dhruv8sh Sep 16, 2026
adfad9a
Merge branch 'main' into fix/dev-proxy-bare-invocation-help
prk-Jr Sep 16, 2026
71264e8
Merge branch 'main' into chore/check-root-markdown-formatting
prk-Jr Sep 16, 2026
a9715d5
Merge branch 'main' into fix/reject-placeholder-partner-pull-tokens
prk-Jr Sep 16, 2026
5c7d4f3
Address review nits on root Markdown format gate
dhruv8sh Sep 16, 2026
1851e98
Merge branch 'chore/check-root-markdown-formatting' of https://github…
dhruv8sh Sep 16, 2026
40b65c6
Narrow DEFAULT_LISTEN visibility and simplify rewrite_host test
dhruv8sh Sep 16, 2026
76bc65d
Merge branch 'main' into fix/align-edgezero-pr-381
aram356 Sep 16, 2026
bdb68dd
Merge feat/request-phase-timing and resolve auction timeline review f…
jevansnyc Sep 17, 2026
58f8a35
Correct the section 18 status line and give the wrangler ignore its o…
jevansnyc Sep 17, 2026
11d3758
Merge branch 'main' into worktree-tester-cookie-max-age
aram356 Sep 17, 2026
dae88a0
Improve GPT auction diagnostics observability
ChristianPavilonis Sep 4, 2026
30ccab8
Fix GPT auction diagnostics timing accuracy
ChristianPavilonis Sep 4, 2026
563670d
Address GPT diagnostics review feedback
ChristianPavilonis Sep 14, 2026
628ce28
Clarify GPT auction diagnostics evidence
ChristianPavilonis Sep 8, 2026
b316aee
Address GPT diagnostics review feedback
ChristianPavilonis Sep 14, 2026
9b5bb41
Align GPT diagnostics tests with current metadata
ChristianPavilonis Sep 17, 2026
54d33ad
Hide placeholder dimensions from diagnostics overlay
ChristianPavilonis Sep 17, 2026
645d641
Open Fastly stores by logical ID on the EdgeZero PR 381 branch head
aram356 Sep 17, 2026
d3bb29d
Read the Fastly config entry under its logical ID on every target
aram356 Sep 17, 2026
86a3df8
Move the EdgeZero pin to the PR 381 branch head dbb95018
aram356 Sep 18, 2026
33f9f2e
Return a static slice from all_module_ids instead of allocating a Vec
dhruv8sh Sep 18, 2026
a5541e2
Merge branch 'main' into fix/tsjs-all-module-ids-allocation
dhruv8sh Sep 18, 2026
1643717
Add regression test asserting Settings debug output excludes secret v…
dhruv8sh Sep 18, 2026
6f95f1d
Reject oversized bid dimensions instead of truncating them
dhruv8sh Sep 18, 2026
2c43347
Move the EdgeZero pin to the PR 381 branch head fba2076a
aram356 Sep 18, 2026
f9d959f
Move the EdgeZero pin to the PR 381 branch head c40ae8d0
aram356 Sep 18, 2026
713daf8
Rewrite Sourcepoint bodies without Content-Length
ChristianPavilonis Sep 18, 2026
713b271
Move the EdgeZero pin to the PR 381 branch head 4531aeec
aram356 Sep 18, 2026
3c9d8c0
Move the EdgeZero pin to the PR 381 branch head 7162b7e2
aram356 Sep 18, 2026
9226cfb
Move the EdgeZero pin to the PR 381 branch head 8b506782
aram356 Sep 18, 2026
7d212b7
Move the EdgeZero pin to the PR 381 branch head fd45db1f
aram356 Sep 18, 2026
c7483aa
Move the EdgeZero pin to the PR 381 branch head 6258b6b2
aram356 Sep 18, 2026
9380c12
Move the EdgeZero pin to the PR 381 branch head bb4e0040
aram356 Sep 19, 2026
b1d41c5
Move the EdgeZero pin to the PR 381 branch head cf9a96a0
aram356 Sep 19, 2026
be595ce
Merge branch 'main' into fix/sourcepoint-unknown-length-1088
aram356 Sep 19, 2026
4295039
Move the EdgeZero pin to the PR 381 branch head 119fbf80
aram356 Sep 19, 2026
1e6fc67
Watch only bundle inputs in the trusted-server-js build script
aram356 Sep 19, 2026
ae47b43
Move the EdgeZero pin to the PR 381 branch head 5878eb74
aram356 Sep 19, 2026
c2aa6be
Merge branch 'main' into spec/mobile-ad-render-trace-endpoint
prk-Jr Sep 19, 2026
e3f371f
Reconcile mobile trace design contracts
prk-Jr Sep 19, 2026
6e9c50c
Select the release manifest in the CLI deploy examples
aram356 Sep 20, 2026
ed82795
Derive ALL_MODULE_IDS from TSJS_MODULES to prevent the two lists drif…
dhruv8sh Sep 20, 2026
95bd289
Reorder root Markdown check, document npm ci prereq
dhruv8sh Sep 20, 2026
3e8cde2
Update crates/trusted-server-js/lib/src/integrations/prebid/index.ts
ChristianPavilonis Sep 20, 2026
d6fecdf
Move the EdgeZero pin to the PR 381 branch head 12c3215c
aram356 Sep 20, 2026
488de2c
Merge branch 'main' into spec/mobile-ad-render-trace-endpoint
prk-Jr Sep 21, 2026
14c274c
Clarify mobile trace design contracts
prk-Jr Sep 21, 2026
39e045f
Merge branch 'main' into fix/align-edgezero-pr-381
prk-Jr Sep 21, 2026
a7b19ca
Address remaining GPT diagnostics review feedback
ChristianPavilonis Sep 21, 2026
f951955
Fix cross-adapter GPT diagnostic timing origins
ChristianPavilonis Sep 21, 2026
58963a8
Strengthen the oversized-dimension regression test
dhruv8sh Sep 21, 2026
b70cb57
Guard the IntegrationSettings debug boundary and correct the test com…
dhruv8sh Sep 21, 2026
57eab4a
Fix placeholder partner secret check to compare resolved values, not …
dhruv8sh Sep 21, 2026
ffd5bf8
Rework proxy CLI arg-parsing tests to cover the real clap defaults
dhruv8sh Sep 22, 2026
855b49b
Merge branch 'main' into fix/adserver-mock-dimension-truncation
prk-Jr Sep 22, 2026
7a82a94
Merge branch 'main' into spec/mobile-ad-render-trace-endpoint
aram356 Sep 24, 2026
dfe3ced
Merge branch 'main' into worktree-tester-cookie-max-age
aram356 Sep 24, 2026
155d3b0
Clarify trace body validation and browser cleanup
prk-Jr Sep 24, 2026
d361b8e
Merge branch 'main' into spec/mobile-ad-render-trace-endpoint
prk-Jr Sep 24, 2026
591b873
Merge branch 'main' into fix/align-edgezero-pr-381
aram356 Sep 24, 2026
a1710a0
Pin EdgeZero to an immutable rev and close the review findings
aram356 Sep 24, 2026
fe35b68
Merge branch 'main' into fix/dev-proxy-bare-invocation-help
aram356 Sep 24, 2026
c469d55
Merge branch 'main' into chore/check-root-markdown-formatting
aram356 Sep 24, 2026
057a647
Merge branch 'main' into fix/dev-proxy-bare-invocation-help
aram356 Sep 24, 2026
30ecb1c
Merge branch 'main' into fix/tsjs-all-module-ids-allocation
aram356 Sep 24, 2026
9654495
Merge branch 'main' into fix/adserver-mock-dimension-truncation
aram356 Sep 24, 2026
7e3997a
Merge branch 'main' into test/settings-debug-output-redacts-secrets
aram356 Sep 24, 2026
bf96305
Pin adserver mock bid dimension boundaries in tests
dhruv8sh Sep 24, 2026
8dd9713
Assert bare proxy invocation via clap's typed error kind
dhruv8sh Sep 24, 2026
d100d1b
Resolve proxy rules before restoring pending system proxy state
dhruv8sh Sep 24, 2026
0fa7dfb
Clarify Prebid diagnostics export boundaries
ChristianPavilonis Sep 25, 2026
c4d664a
Merge branch 'main' into spec/mobile-ad-render-trace-endpoint
aram356 Sep 25, 2026
4d0ca8d
Merge branch 'main' into fix/sourcepoint-unknown-length-1088
aram356 Sep 26, 2026
325cca7
Merge branch 'main' into chore/check-root-markdown-formatting
aram356 Sep 26, 2026
b4413d2
Merge branch 'main' into fix/reject-placeholder-partner-pull-tokens
aram356 Sep 28, 2026
819ac71
Parse mock bid dimensions with the shared OpenRTB helper
dhruv8sh Sep 28, 2026
7eed6a3
Validate mock mediated bid dimensions against requested slots
dhruv8sh Sep 28, 2026
44fb9c2
Extend the Markdown format check beyond the repo root
dhruv8sh Sep 28, 2026
d7dcb18
Test that both partner token placeholders are reported together
dhruv8sh Sep 28, 2026
054b3a3
Merge branch 'main' into worktree-tester-cookie-max-age
aram356 Sep 28, 2026
eb2bae2
Merge branch 'main' into fix/reject-placeholder-partner-pull-tokens
aram356 Sep 28, 2026
4552fcf
Fix Sourcepoint HEAD pass-through test
ChristianPavilonis Sep 28, 2026
a180741
Merge branch 'main' into spec/mobile-ad-render-trace-endpoint
prk-Jr Sep 30, 2026
4811d98
Clarify trace failure and export cleanup contracts
prk-Jr Oct 1, 2026
162b3a4
Merge branch 'main' into spec/mobile-ad-render-trace-endpoint
prk-Jr Oct 1, 2026
35ca367
Merge branch 'main' into test/settings-debug-output-redacts-secrets
dhruv8sh Oct 1, 2026
44144f0
Merge branch 'main' into fix/tsjs-all-module-ids-allocation
dhruv8sh Oct 1, 2026
21eb725
Merge branch 'main' into fix/dev-proxy-bare-invocation-help
dhruv8sh Oct 1, 2026
4170c4c
Merge branch 'main' into fix/reject-placeholder-partner-pull-tokens
dhruv8sh Oct 1, 2026
4b03d6c
Merge branch 'main' into fix/adserver-mock-dimension-truncation
dhruv8sh Oct 1, 2026
7dc5638
Merge branch 'main' into chore/check-root-markdown-formatting
dhruv8sh Oct 1, 2026
d163be2
Merge branch 'main' into worktree-tester-cookie-max-age
aram356 Oct 1, 2026
b253a00
Merge branch 'main' into fix/sourcepoint-unknown-length-1088
aram356 Oct 1, 2026
209fbb2
Merge PR #1175 into rc/202610
ChristianPavilonis Oct 1, 2026
ad78650
Merge PR #1074 into rc/202610
ChristianPavilonis Oct 1, 2026
db1e1ed
Merge PR #1052 into rc/202610
ChristianPavilonis Oct 1, 2026
6968164
Merge September revision of PR #1121 into October RC
ChristianPavilonis Oct 1, 2026
f93d652
Merge PR #1154 into rc/202610
ChristianPavilonis Oct 1, 2026
51513e4
Merge PR #1107 into rc/202610
ChristianPavilonis Oct 1, 2026
7f1e736
Merge PR #1137 into rc/202610
ChristianPavilonis Oct 1, 2026
77ad504
Merge PR #1183 into rc/202610
ChristianPavilonis Oct 1, 2026
dca291c
Merge PR #1173 into rc/202610
ChristianPavilonis Oct 1, 2026
7e06e69
Merge PR #1176 into rc/202610
ChristianPavilonis Oct 1, 2026
6b082b1
Merge PR #1177 into rc/202610
ChristianPavilonis Oct 1, 2026
2f3eed7
Merge PR #1180 into rc/202610
ChristianPavilonis Oct 1, 2026
abba833
Merge PR #1181 into rc/202610
ChristianPavilonis Oct 1, 2026
22ce7b7
Merge PR #1182 into rc/202610
ChristianPavilonis Oct 1, 2026
217dd43
Allow bounded cold browser launches in audits
ChristianPavilonis Oct 1, 2026
9988c97
Merge main into rc/202610
ChristianPavilonis Oct 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,7 @@ src/*.html
# leftover local build artifacts (node_modules, target, dist) that remain on disk.
/crates/js/
/crates/integration-tests/

# Wrangler config generated by the Cloudflare integration-test harness from
# wrangler.toml at run time; regenerated on every run.
wrangler.integration.generated.toml
21 changes: 13 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ cssparser = "0.36"
derive_more = { version = "2.0", features = ["display", "error"] }
directories = "5"
ed25519-dalek = { version = "2.2", features = ["rand_core"] }
edgezero-adapter-axum = { git = "https://github.com/stackpop/edgezero", tag = "v0.0.8", default-features = false }
edgezero-adapter-cloudflare = { git = "https://github.com/stackpop/edgezero", tag = "v0.0.8", default-features = false }
edgezero-adapter-fastly = { git = "https://github.com/stackpop/edgezero", tag = "v0.0.8", default-features = false }
edgezero-adapter-spin = { git = "https://github.com/stackpop/edgezero", tag = "v0.0.8", default-features = false }
edgezero-cli = { git = "https://github.com/stackpop/edgezero", tag = "v0.0.8" }
edgezero-core = { git = "https://github.com/stackpop/edgezero", tag = "v0.0.8", default-features = false }
edgezero-adapter-axum = { git = "https://github.com/stackpop/edgezero", rev = "12c3215c2637d961a27eefa12e235033fadb4c4a", default-features = false }
edgezero-adapter-cloudflare = { git = "https://github.com/stackpop/edgezero", rev = "12c3215c2637d961a27eefa12e235033fadb4c4a", default-features = false }
edgezero-adapter-fastly = { git = "https://github.com/stackpop/edgezero", rev = "12c3215c2637d961a27eefa12e235033fadb4c4a", default-features = false }
edgezero-adapter-spin = { git = "https://github.com/stackpop/edgezero", rev = "12c3215c2637d961a27eefa12e235033fadb4c4a", default-features = false }
edgezero-cli = { git = "https://github.com/stackpop/edgezero", rev = "12c3215c2637d961a27eefa12e235033fadb4c4a" }
edgezero-core = { git = "https://github.com/stackpop/edgezero", rev = "12c3215c2637d961a27eefa12e235033fadb4c4a", default-features = false }
env_logger = "0.11"
error-stack = "0.6"
esi = "0.7.2"
Expand Down
5 changes: 3 additions & 2 deletions crates/trusted-server-adapter-axum/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,16 @@ path = "src/main.rs"

[dependencies]
async-trait = { workspace = true }
axum = { workspace = true }
edgezero-adapter-axum = { workspace = true, features = ["axum"] }
edgezero-core = { workspace = true }
error-stack = { workspace = true }
futures = { workspace = true }
log = { workspace = true }
reqwest = { workspace = true }
simple_logger = { workspace = true }
tokio = { workspace = true, features = ["rt-multi-thread", "macros", "sync", "time"] }
tokio = { workspace = true, features = ["rt-multi-thread", "macros", "net", "signal", "sync", "time"] }
tower = { workspace = true, features = ["util"] }
trusted-server-core = { workspace = true }

[dev-dependencies]
Expand All @@ -36,4 +38,3 @@ axum = { workspace = true }
base64 = { workspace = true }
temp-env = { workspace = true }
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
tower = { workspace = true, features = ["util"] }
49 changes: 40 additions & 9 deletions crates/trusted-server-adapter-axum/src/app.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use core::future::Future;
use std::sync::Arc;

use edgezero_adapter_axum::service::EdgeZeroAxumService;
use edgezero_core::app::Hooks;
use edgezero_core::context::RequestContext;
use edgezero_core::error::EdgeError;
Expand Down Expand Up @@ -616,15 +617,7 @@ impl Hooks for TrustedServerApp {
}

fn routes() -> RouterService {
let state = match build_state() {
Ok(s) => s,
Err(ref e) => {
log::error!("failed to build application state: {:?}", e);
return startup_error_router(e);
}
};

build_router(&state)
Self::routes_with_server_timing_flag().0
}
}

Expand Down Expand Up @@ -669,6 +662,44 @@ impl TrustedServerApp {
let state = build_state_with_services(settings, Some(services))?;
Ok(build_router(&state))
}

/// The dev server's fully configured tower service: the application
/// router wrapped in the terminal timing layer
/// ([`crate::timing::TimingService`]), with `server_timing_enabled`
/// read from the same settings snapshot that built the router.
///
/// This is the standard construction path for serving this adapter.
/// [`Hooks::routes`] satisfies the `Hooks` trait contract and returns
/// the bare router without the timing layer; callers who serve traffic
/// should use this instead so `server_timing_enabled` is never
/// silently discarded.
#[must_use]
pub fn dev_server_service() -> crate::timing::TimingService<EdgeZeroAxumService> {
let (router, server_timing_enabled) = Self::routes_with_server_timing_flag();
crate::timing::TimingService::new(EdgeZeroAxumService::new(router), server_timing_enabled)
}

/// Build the router alongside whether `Server-Timing` emission is
/// enabled, read from the same settings snapshot used to build the
/// router.
///
/// The Axum dev server's terminal timing layer ([`crate::timing`]) needs
/// this flag once at startup: unlike the Fastly adapter, which rebuilds
/// `Settings` per request, the Axum dev server builds its application
/// state once and reuses the same [`RouterService`] for every request.
#[must_use]
fn routes_with_server_timing_flag() -> (RouterService, bool) {
let state = match build_state() {
Ok(s) => s,
Err(ref e) => {
log::error!("failed to build application state: {:?}", e);
return (startup_error_router(e), false);
}
};

let server_timing_enabled = state.settings.observability.server_timing_enabled;
(build_router(&state), server_timing_enabled)
}
}

fn build_router(state: &Arc<AppState>) -> RouterService {
Expand Down
3 changes: 3 additions & 0 deletions crates/trusted-server-adapter-axum/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@ pub mod app;
pub mod middleware;
/// Platform-trait implementations backed by env vars and `reqwest`.
pub mod platform;
/// Terminal timing layer wrapping the Axum dev server's tower `Service`
/// boundary with the request-phase `Server-Timing` freeze point.
pub mod timing;
67 changes: 63 additions & 4 deletions crates/trusted-server-adapter-axum/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
use edgezero_adapter_axum::dev_server::{AxumDevServer, AxumDevServerConfig};
use edgezero_core::app::Hooks as _;
use std::net::SocketAddr;

use axum::Router;
use edgezero_adapter_axum::dev_server::AxumDevServerConfig;
use edgezero_adapter_axum::service::EdgeZeroAxumService;
use tokio::net::TcpListener;
use tokio::runtime::Builder as RuntimeBuilder;
use tokio::signal;
use tower::Service as _;
use tower::service_fn;
use trusted_server_adapter_axum::app::TrustedServerApp;
use trusted_server_adapter_axum::timing::TimingService;

#[allow(clippy::print_stderr)]
fn main() {
Expand All @@ -20,13 +29,63 @@ fn main() {
};

log::info!("Listening on http://{}", config.addr);
let router = TrustedServerApp::routes();
if let Err(err) = AxumDevServer::with_config(router, config).run() {
let service = TrustedServerApp::dev_server_service();
if let Err(err) = run(service, config) {
log::error!("trusted-server-adapter-axum failed: {err}");
std::process::exit(1);
}
}

/// Runs the Axum dev server with the request-phase timing terminal layer
/// ([`trusted_server_adapter_axum::timing::TimingService`]) wrapped around
/// `EdgeZeroAxumService`, ahead of `axum::serve`.
///
/// This does not use `edgezero_adapter_axum::dev_server::AxumDevServer::run`:
/// that helper only accepts a bare [`RouterService`] and builds its own
/// `EdgeZeroAxumService` and `axum::Router` internally, with no seam for an
/// outer service wrapper. Router-generated 404/405 responses bypass
/// `RouterBuilder::middleware` (see `trusted_server_adapter_axum::timing`),
/// so the freeze point has to wrap the tower `Service` boundary itself.
/// Driving `axum::serve` directly here mirrors that helper's own internal
/// bind/wrap/serve/shutdown sequence closely enough to keep behavior
/// identical for callers (`PORT` env var, ctrl-c graceful shutdown).
///
/// # Errors
///
/// Returns an error if the Tokio runtime fails to start, the listener fails
/// to bind, or the underlying serve loop errors.
fn run(
service: TimingService<EdgeZeroAxumService>,
config: AxumDevServerConfig,
) -> std::io::Result<()> {
let runtime = RuntimeBuilder::new_multi_thread().enable_all().build()?;
runtime.block_on(serve(service, config))
}

async fn serve(
service: TimingService<EdgeZeroAxumService>,
config: AxumDevServerConfig,
) -> std::io::Result<()> {
let listener = TcpListener::bind(config.addr).await?;

let axum_router = Router::new().fallback_service(service_fn(move |req| {
let mut svc = service.clone();
async move { svc.call(req).await }
}));
let make_service = axum_router.into_make_service_with_connect_info::<SocketAddr>();

let server = axum::serve(listener, make_service);
if config.enable_ctrl_c {
server
.with_graceful_shutdown(async {
let _ctrl_c = signal::ctrl_c().await;
})
.await
} else {
server.await
}
}

/// Read a port number from the `PORT` environment variable.
///
/// Returns `None` when the variable is unset. Exits non-zero if the value
Expand Down
Loading
Loading