This is an automated email from the ASF dual-hosted git repository.
jamesbognar pushed a commit to branch docs
in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/docs by this push:
new 28fcd80fa0 TODO-117/118/121/128 - MdcAsyncListener, async completion
executor, lazy children materialization, ParameterInfo Optional wrapping
28fcd80fa0 is described below
commit 28fcd80fa01205d217c9ab5a3ad7749573be9be0
Author: James Bognar <[email protected]>
AuthorDate: Fri May 29 10:59:12 2026 -0400
TODO-117/118/121/128 - MdcAsyncListener, async completion executor, lazy
children materialization, ParameterInfo Optional wrapping
---
pages/release-notes/9.5.0.md | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/pages/release-notes/9.5.0.md b/pages/release-notes/9.5.0.md
index 1675afa2c9..5786563f58 100644
--- a/pages/release-notes/9.5.0.md
+++ b/pages/release-notes/9.5.0.md
@@ -2278,6 +2278,41 @@ String name
### juneau-rest-server
+#### Opt-in lazy `@Rest(children=...)` materialization (TODO-121)
+
+Parent resources annotated with `@Rest(lazyChildren=true)` now defer the
construction of each child
+`RestContext` until the first HTTP request routed to that child. Default
behavior (eager at startup)
+is unchanged for all existing code.
+
+- **`@Rest(lazyChildren="true")`** on the parent resource opts all declared
`@Rest(children=...)` into
+ deferred (first-invocation) construction. The value is a `String` member
with full SVL variable
+ support (e.g. `@Rest(lazyChildren="$E{LAZY_CHILDREN,false}")`).
+- **`RestContext.Builder.lazyChildInit(boolean)`** is the host-wide
programmatic knob with the highest
+ resolution priority (overrides both annotation and
`${RestContext.lazyChildren:false}` env default).
+- **Shell-context routing:** At parent startup the route table is fully
populated — each lazy child
+ contributes its path prefix (resolved from `@Rest(path=...)` without
instantiating a full context)
+ to the parent's `RestChildren` matcher list. URL matching works
immediately; the full `RestContext`
+ is built only on the first matching request.
+- **Concurrency safety:** Exactly one materialization per child even under
concurrent first-requests.
+ `RestChildren.LazyChildEntry.materialize()` uses a double-checked lock on a
per-entry `Object lock`
+ with a `volatile RestContext materialized` field. Two simultaneous
first-requests serialize on the
+ lock; the second thread reads the already-built context without
re-constructing. A materialization
+ that throws leaves the `materialized` field `null` — the next request
retries.
+- **Observability:** Materialization is logged at `INFO` level:
+ `Lazy REST child materializing: com.example.ChildResource at path '/child'`
/ `materialized`.
+- **Lifecycle:** `RestContext.destroy()` (via `RestChildren.destroy()`) only
calls the child's
+ shutdown hooks if the child was actually materialized. Never-invoked
children are silently skipped.
+- **Interaction with `@Rest(observability="true")` (TODO-115):** Startup-fail
is also deferred —
+ the observability-backend wiring check fires when the lazy child is first
materialized, not at
+ parent startup.
+
+```java
+@Rest(path="/api", children={AdminResource.class, MonitorResource.class},
lazyChildren="true")
+public class ApiGroupResource extends BasicRestServletGroup {
+ // AdminResource and MonitorResource are built only on first request
+}
+```
+
#### Outgoing-response W3C trace-context headers (TODO-114)
When a non-no-op `TracerHook` is active on a request, the server now writes
the W3C `traceparent` — and, when present, the `tracestate` — header back onto
the HTTP **response**, so a client calling the server can read the resulting
trace id off the response and correlate against it. The emitted `traceparent`
reflects the **server-started span's** context (a freshly-minted span id
parented to the inbound trace), not the inbound header verbatim. `tracestate`
is written **only when the acti [...]