From 93afc5fe4552f0d468aadeb8c8069d8f9ca88436 Mon Sep 17 00:00:00 2001 From: Nanaloveyuki Date: Sun, 14 Jun 2026 09:56:11 +0800 Subject: [PATCH] :memo: clarify library async facade state preservation --- docs/api/library-async-logger.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/api/library-async-logger.md b/docs/api/library-async-logger.md index cc66c1e..fac1caf 100644 --- a/docs/api/library-async-logger.md +++ b/docs/api/library-async-logger.md @@ -35,11 +35,13 @@ Detailed rules explaining key parameters and behaviors - The wrapped sink type `S` is preserved, so sink-specific typing remains available through the facade type parameter. - The facade keeps common library-safe async operations such as `new(...)`, `with_target(...)`, `child(...)`, `bind(...)`, `is_enabled(...)`, `run()`, `shutdown()`, and the main async write methods `log(...)`, `info(...)`, `warn(...)`, and `error(...)`. - `LibraryAsyncLogger::new(...)` delegates to `async_logger(...)`, so the same async queue, raising flush callback, and runtime-dependent lifecycle behavior still exist behind the narrower facade. +- Because `new(...)` delegates directly, `AsyncLoggerConfig` values such as pending limits, overflow mode, batch sizing, linger timing, and flush policy are preserved exactly rather than being translated into facade-specific defaults. - The facade also preserves the wrapped async logger's target rules on its exposed write methods: `log(..., target=...)` can override the target for one call, while `info(...)`, `warn(...)`, and `error(...)` continue using the stored logger target unless the facade first derives another logger with `with_target(...)` or `child(...)`. - Most facade reshaping helpers keep the same visible sink type, and unlike synchronous `LibraryLogger`, async `with_context_fields(...)` and `bind(...)` also preserve the visible `LibraryAsyncLogger[S]` type because they update stored async context metadata instead of changing the exposed sink wrapper. - It does not expose the wider `AsyncLogger[S]` composition surface or the async state and lifecycle inspection helpers directly. - Call `to_async_logger()` when later code must recover the full underlying `AsyncLogger[S]` surface. - That recovered logger is the same live async value, so queue counters, retained failure state, runtime-dependent shutdown outcomes, and sink helper access are preserved rather than recomputed. +- If the delegated async flush callback fails, the facade preserves the same `has_failed()`, `last_error()`, `is_running()`, pending-backlog, and shutdown-cleanup semantics that the underlying `AsyncLogger[S]` would have exposed directly. - If `S` is `RuntimeSink`, queued runtime state and file-backed helper behavior also stay on that same wrapped logger value; the facade only hides direct access until `to_async_logger()` is used. ### How to Use @@ -101,6 +103,8 @@ e.g.: - If the wrapped async logger later ends in a mixed diagnostic state such as `has_failed=true` with retained backlog, unwrapping exposes that exact state instead of a library-specific translation. +- Shutdown through the facade keeps the wrapped logger's runtime-dependent failure cleanup behavior: after a worker-side failure, unwrapped pending versus dropped cleanup can still differ between native-worker and compatibility runtimes. + - Helpers such as `pending_count()`, `dropped_count()`, `is_closed()`, `is_running()`, `has_failed()`, `last_error()`, `flush_policy()`, `state()`, and `wait_idle()` remain on the underlying `AsyncLogger[S]` and require `to_async_logger()` first. ### Notes