From 83371bb4d54a6b7b24a1a05053a8ede7dcb79db6 Mon Sep 17 00:00:00 2001 From: Nanaloveyuki Date: Tue, 7 Jul 2026 11:25:02 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9D=20=E8=A1=A5=E5=85=85runtime?= =?UTF-8?q?=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/api/configured-logger-close.md | 22 +++-- docs/api/configured-logger-drain-progress.md | 79 +++++++++++++++++ docs/api/configured-logger-drain.md | 35 +++++--- .../configured-logger-file-clear-rotation.md | 45 ++-------- docs/api/configured-logger-file-close.md | 15 ++-- docs/api/configured-logger-file-flush.md | 18 ++-- docs/api/configured-logger-file-reopen.md | 9 +- .../configured-logger-file-reset-policy.md | 55 ++---------- .../configured-logger-file-set-append-mode.md | 9 +- .../configured-logger-file-set-auto-flush.md | 9 +- docs/api/configured-logger-file-set-policy.md | 9 +- .../configured-logger-file-set-rotation.md | 48 +++-------- docs/api/configured-logger-flush-progress.md | 78 +++++++++++++++++ docs/api/configured-logger-flush.md | 35 +++++--- docs/api/configured-logger.md | 5 +- docs/api/runtime-sink-close.md | 20 +++-- docs/api/runtime-sink-drain-progress.md | 80 +++++++++++++++++ docs/api/runtime-sink-drain.md | 38 +++++---- docs/api/runtime-sink-file-clear-rotation.md | 47 ++-------- docs/api/runtime-sink-file-close.md | 16 ++-- docs/api/runtime-sink-file-flush.md | 18 ++-- docs/api/runtime-sink-file-reopen.md | 9 +- docs/api/runtime-sink-file-reset-policy.md | 55 ++---------- docs/api/runtime-sink-file-set-append-mode.md | 9 +- docs/api/runtime-sink-file-set-auto-flush.md | 9 +- docs/api/runtime-sink-file-set-policy.md | 9 +- docs/api/runtime-sink-file-set-rotation.md | 43 +++------- docs/api/runtime-sink-flush-progress.md | 79 +++++++++++++++++ docs/api/runtime-sink-flush.md | 38 +++++---- docs/api/runtime-sink-progress.md | 85 +++++++++++++++++++ docs/api/runtime-sink.md | 5 +- 31 files changed, 664 insertions(+), 367 deletions(-) create mode 100644 docs/api/configured-logger-drain-progress.md create mode 100644 docs/api/configured-logger-flush-progress.md create mode 100644 docs/api/runtime-sink-drain-progress.md create mode 100644 docs/api/runtime-sink-flush-progress.md create mode 100644 docs/api/runtime-sink-progress.md diff --git a/docs/api/configured-logger-close.md b/docs/api/configured-logger-close.md index 325ef66..3836869 100644 --- a/docs/api/configured-logger-close.md +++ b/docs/api/configured-logger-close.md @@ -2,8 +2,8 @@ name: configured-logger-close group: api category: runtime -update-time: 20260613 -description: Close the configured runtime logger sink and return whether the wrapped RuntimeSink reported a successful close action. +update-time: 20260707 +description: Close the configured runtime logger sink and return whether the wrapped RuntimeSink close path succeeded. key-word: - logger - runtime @@ -27,7 +27,7 @@ pub fn ConfiguredLogger::close(self : ConfiguredLogger) -> Bool {} #### output -- `Bool` - Whether the wrapped `RuntimeSink::close(...)` call reported a successful close action. +- `Bool` - Whether the wrapped `RuntimeSink::close(...)` call reported a successful close path. ### Explanation @@ -35,9 +35,11 @@ Detailed rules explaining key parameters and behaviors - This helper delegates directly to `self.sink.close()`. - Plain file sinks forward to `FileSink::close()` through `RuntimeSink`. -- Queue-backed file sinks close the wrapped file sink instead of only the queue wrapper. -- Generic `close()` on queued file sinks does not drain pending queue entries first; it closes the wrapped file sink directly. -- Console-style sinks and queue-wrapped console-style sinks return `true` as a no-op success because they do not expose a meaningful close step here. +- Queue-backed file sinks now follow the same safe teardown path as `file_close()`: they first try to drain the queue, then flush the wrapped inner file sink, then close it. +- On queued file sinks, the returned `Bool` is `true` only when that whole teardown path succeeds without introducing new file failures. +- Plain console-style sinks return `true` as a no-op success because they do not expose a meaningful close step here. +- Queue-wrapped console-style sinks now use drain-first teardown before returning `true`. +- For `QueuedConsole`, `QueuedJsonConsole`, and `QueuedTextConsole`, success means the queued backlog was consumed to zero. - For file-backed configured loggers, later `close()` calls return `false` after the wrapped file handle has already been cleared. ### How to Use @@ -69,12 +71,16 @@ e.g.: - If the configured logger shares the same wrapped runtime sink state with another facade and one path already closed that file-backed sink, a later close attempt returns `false`. -- If callers need a file-specific close path with queue flush nuances, `file_close()` may be the better API. +- If callers need a file-specific close path with queue flush nuances, `file_close()` may still be the clearer API. + +- On queued file sinks, `true` still does not mean the records are guaranteed to be durable beyond what the current backend can report; it means the queue-drain, file-flush, and file-close path completed without a newly observed file failure. + +- On queued non-file sinks, `true` means the queued backlog was consumed before teardown completed. ### Notes 1. This is the generic configured runtime close helper. -2. Prefer `file_close()` when the configured sink shape is file-backed and queued records should be flushed before teardown. +2. Generic `close()` is now safe for queue-backed runtime sinks and no longer skips queued records silently. 3. Converting the same configured logger through wrapper paths such as library projection still shares the wrapped runtime sink state, so close effects are visible across those facades. diff --git a/docs/api/configured-logger-drain-progress.md b/docs/api/configured-logger-drain-progress.md new file mode 100644 index 0000000..6611578 --- /dev/null +++ b/docs/api/configured-logger-drain-progress.md @@ -0,0 +1,79 @@ +--- +name: configured-logger-drain-progress +group: api +category: runtime +update-time: 20260707 +description: Return a structured generic drain progress snapshot for a ConfiguredLogger through RuntimeSink without collapsing queue and plain-file fallback semantics into one Int. +key-word: + - logger + - runtime + - drain + - public +--- + +## Configured-logger-drain-progress + +Return a structured generic drain progress snapshot for a `ConfiguredLogger`. This is the recommended configured runtime wrapper over `RuntimeSink::drain_progress(...)` when code wants truthful generic progress instead of the compatibility `Int` returned by `drain()`. + +### Interface + +```moonbit +pub fn ConfiguredLogger::drain_progress( + self : ConfiguredLogger, + max_items~ : Int = -1, +) -> RuntimeSinkProgress {} +``` + +#### input + +- `self : ConfiguredLogger` - Config-driven runtime logger whose generic drain progress should be observed. +- `max_items : Int` - Optional upper bound on drained queued items. Negative values mean no explicit bound. + +#### output + +- `RuntimeSinkProgress` - Structured progress snapshot returned by the wrapped `RuntimeSink::drain_progress(...)` call. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This helper delegates directly to `self.sink.drain_progress(max_items=max_items)`. +- Queue-wrapped sinks report drained queued items through `queue_advanced_count`. +- Plain file sinks report the generic fallback flush step through `file_flush_step_count`. +- Plain console-style sinks return a zeroed snapshot. +- This helper keeps configured-runtime drain behavior explicit without forcing callers to interpret one mixed `Int`. + +### How to Use + +Here are some specific examples provided. + +#### When Need Recommended Bounded Generic Drain Progress On A Config-built Logger + +When queued config-built output should be advanced in chunks with explicit semantics: +```moonbit +let progress = logger.drain_progress(max_items=16) +``` + +In this example, queue advancement and plain-file fallback stay separated. + +#### When Need Full Manual Generic Drain Progress + +When config-built support code should empty runtime queue work while keeping shape information: +```moonbit +let progress = logger.drain_progress() +``` + +In this example, the structured result still tells whether the logger was queue-backed or plain file-backed. + +### Error Case + +e.g.: +- If the configured runtime sink is not queue-backed, the snapshot may stay zeroed or use the plain-file fallback field. + +- If callers need file-specific success semantics after queue delivery, `file_flush()` is the better API. + +### Notes + +1. Prefer `drain_progress()` over `drain()` in new configured-runtime code. + +2. Use `pending_count()` together with this helper when remaining backlog should also be observed. diff --git a/docs/api/configured-logger-drain.md b/docs/api/configured-logger-drain.md index 2bb8bea..f97e0b5 100644 --- a/docs/api/configured-logger-drain.md +++ b/docs/api/configured-logger-drain.md @@ -2,8 +2,8 @@ name: configured-logger-drain group: api category: runtime -update-time: 20260613 -description: Drain queued work from a configured runtime logger with optional item limits through RuntimeSink. +update-time: 20260707 +description: Compatibility configured runtime drain helper that still returns one Int by collapsing generic queue progress and plain-file fallback steps. key-word: - logger - runtime @@ -13,7 +13,7 @@ key-word: ## Configured-logger-drain -Drain queued work from a `ConfiguredLogger`. This helper is the configured logger wrapper over `RuntimeSink::drain(...)` when config-driven queue wrapping should be advanced in a controlled, bounded way. +Drain queued work from a `ConfiguredLogger` and return one compatibility count. This helper is still available for older code, but new configured-runtime code should prefer `drain_progress()` because it exposes queue advancement and plain-file fallback steps separately. ### Interface @@ -28,16 +28,17 @@ pub fn ConfiguredLogger::drain(self : ConfiguredLogger, max_items~ : Int = -1) - #### output -- `Int` - Count returned by the wrapped `RuntimeSink::drain(...)` call. +- `Int` - Compatibility count returned by the wrapped `RuntimeSink::drain(...)` call. ### Explanation Detailed rules explaining key parameters and behaviors - This helper delegates directly to `self.sink.drain(max_items=max_items)`. -- Queue-wrapped sinks forward to the concrete queue sink's `drain(...)` behavior and may drain up to `max_items` records. -- Plain file sinks fall back to `FileSink::flush()` behavior through `RuntimeSink` and return `1` or `0`. -- Plain console-style sinks return `0` because they do not own a drainable queue here. +- Under the hood, `RuntimeSink::drain()` now rebuilds one compatibility count from `drain_progress()`. +- Queue-wrapped sinks still report drained queued items through that compatibility count. +- Plain file sinks still report the generic fallback flush step as `1` or `0`. +- Plain console-style sinks still return `0`. ### How to Use @@ -45,31 +46,37 @@ Here are some specific examples provided. #### When Need Bounded Queue Progress -When queued output should be advanced in chunks: +When older code already expects one numeric drain count from a config-built logger: ```moonbit let drained = logger.drain(max_items=16) ``` -In this example, callers limit how much queued work is processed in one step. +In this example, callers still limit how much queued work is processed in one step while keeping the legacy return shape. #### When Need Full Manual Drain -When the configured queue should be emptied explicitly: +When code should keep the older full-drain compatibility path: ```moonbit ignore(logger.drain()) ``` -In this example, the configured runtime logger drains without imposing an item cap. +In this example, the configured runtime logger drains without changing the legacy return shape. ### Error Case e.g.: - If the configured runtime sink is not queue-backed, draining may return `0` or follow the plain-file flush fallback. -- If callers only need generic flush semantics, `flush()` may be the simpler API. +- If callers need truthful generic progress semantics, `drain_progress()` is the better API. + +- If callers only need generic flush semantics, `flush_progress()` may be the simpler structured API. + +- If callers need file-specific success semantics after draining a queued file logger, they should inspect failure counters or use `file_flush()` for the file-specific path. ### Notes -1. Prefer this helper when queue progress should be bounded or observable. +1. Treat this method as a compatibility helper for older numeric code. -2. Use `pending_count()` to inspect remaining backlog after the drain call when the configured sink is queue-backed. +2. Prefer `drain_progress()` in new configured-runtime code. + +3. Use `pending_count()` to inspect remaining backlog after the drain call when the configured sink is queue-backed. diff --git a/docs/api/configured-logger-file-clear-rotation.md b/docs/api/configured-logger-file-clear-rotation.md index ed0238a..f6bb010 100644 --- a/docs/api/configured-logger-file-clear-rotation.md +++ b/docs/api/configured-logger-file-clear-rotation.md @@ -2,8 +2,8 @@ name: configured-logger-file-clear-rotation group: api category: runtime -update-time: 20260512 -description: Disable runtime rotation on the configured file-backed logger sink. +update-time: 20260707 +description: Clear the rotation policy used by the configured runtime file sink. key-word: - logger - runtime @@ -13,7 +13,7 @@ key-word: ## Configured-logger-file-clear-rotation -Disable runtime rotation on a `ConfiguredLogger` file sink. This helper is the direct shortcut for clearing rotation policy. +Clear the rotation policy used by a `ConfiguredLogger` file sink. ### Interface @@ -23,7 +23,7 @@ pub fn ConfiguredLogger::file_clear_rotation(self : ConfiguredLogger) -> Bool {} #### input -- `self : ConfiguredLogger` - Config-driven runtime logger whose rotation policy should be cleared. +- `self : ConfiguredLogger` - Config-driven runtime logger whose file rotation policy should be cleared. #### output @@ -34,41 +34,12 @@ pub fn ConfiguredLogger::file_clear_rotation(self : ConfiguredLogger) -> Bool {} Detailed rules explaining key parameters and behaviors - File-backed sinks clear their runtime rotation policy through the wrapped `RuntimeSink`. -- Queued file sinks forward the update to the wrapped inner file sink. +- Queued file sinks clear the wrapped inner file sink rotation policy only when no queued records are pending. - Non-file sinks return `false`. -- This helper is equivalent in intent to setting rotation to `None`, but is clearer at the call site. - -### How to Use - -Here are some specific examples provided. - -#### When Need To Disable Rotation Explicitly - -When runtime file rotation should be turned off: -```moonbit -ignore(logger.file_clear_rotation()) -``` - -In this example, rotation policy is removed directly. - -#### When Need A Clear Intent Shortcut - -When code should make the disable-rotation intent obvious: -```moonbit -let ok = logger.file_clear_rotation() -``` - -In this example, the call site reads more clearly than a generic config setter. - -### Error Case - -e.g.: -- If the configured sink is not file-backed, the method returns `false`. - -- If callers need to switch to another rotation config rather than disable rotation, `file_set_rotation(...)` is the better API. +- If a queued file sink still has pending records, the update is rejected and returns `false` so already queued records are not later written under a different rotation policy than the one they were queued under. ### Notes -1. Use this helper when the desired effect is simply “rotation off”. +1. Use this helper when runtime rotation policy should be removed without rebuilding the logger. -2. It is clearer than passing `None` through a broader setter when intent matters. +2. On queued file sinks, clear pending records first so policy mutation does not retroactively affect already queued writes. diff --git a/docs/api/configured-logger-file-close.md b/docs/api/configured-logger-file-close.md index 9749780..fa66447 100644 --- a/docs/api/configured-logger-file-close.md +++ b/docs/api/configured-logger-file-close.md @@ -2,8 +2,8 @@ name: configured-logger-file-close group: api category: runtime -update-time: 20260512 -description: Close the file sink behind a configured runtime logger when one is present. +update-time: 20260707 +description: Close the file sink behind a configured runtime logger when one is present, with queued-file success tied to safe drain-flush-close behavior. key-word: - logger - runtime @@ -27,14 +27,15 @@ pub fn ConfiguredLogger::file_close(self : ConfiguredLogger) -> Bool {} #### output -- `Bool` - Whether the underlying file close succeeded. +- `Bool` - Whether the file-specific close path succeeded. ### Explanation Detailed rules explaining key parameters and behaviors - Plain file sinks forward directly to file close behavior through the wrapped `RuntimeSink`. -- Queued file sinks flush queue work before closing the wrapped inner file sink. +- Queued file sinks first drain the queue, then flush the wrapped inner file sink, then close it. +- For queued file sinks, the returned `Bool` is `true` only when that whole path succeeds and no new write, flush, or rotation failures are observed during the drain-flush-close step. - Non-file sinks return `false`. - This helper is narrower than generic `close()` because it specifically targets file sink shutdown. - After a file-backed configured logger has already cleared its file handle, later `file_close()` calls return `false`. @@ -59,7 +60,7 @@ When application code wants the file close outcome directly: let closed = logger.file_close() ``` -In this example, the result describes file close behavior rather than generic sink close behavior. +In this example, the result describes the file-specific close path rather than generic sink close behavior. ### Error Case @@ -70,10 +71,12 @@ e.g.: - If callers only need generic sink teardown, `close()` is the broader API. +- On queued file sinks, `true` still does not mean a stronger durability contract than the current backend can report; it means the safe drain-flush-close path completed without a newly observed file failure. + ### Notes 1. Prefer this helper when file-backed runtime behavior matters specifically. -2. Queued file sinks flush pending records before closing the file, unlike generic `close()`. +2. Generic `close()` now uses the same safe queued-file teardown path. 3. Library or application facades derived from the same configured runtime logger still observe the same underlying file-close state. diff --git a/docs/api/configured-logger-file-flush.md b/docs/api/configured-logger-file-flush.md index 6da4461..6ad3cea 100644 --- a/docs/api/configured-logger-file-flush.md +++ b/docs/api/configured-logger-file-flush.md @@ -2,8 +2,8 @@ name: configured-logger-file-flush group: api category: runtime -update-time: 20260614 -description: Flush the file sink behind a configured runtime logger when one is present. +update-time: 20260707 +description: Flush the file sink behind a configured runtime logger when one is present, with queued-file success tied to both queue drain and file flush outcome. key-word: - logger - runtime @@ -27,16 +27,16 @@ pub fn ConfiguredLogger::file_flush(self : ConfiguredLogger) -> Bool {} #### output -- `Bool` - Whether the underlying file flush succeeded. +- `Bool` - Whether the file-specific flush path succeeded. ### Explanation Detailed rules explaining key parameters and behaviors - Plain file sinks forward directly to file flush behavior through the wrapped `RuntimeSink`. -- Queued file sinks first flush queued records, then flush the wrapped inner file sink. -- For queued file sinks, the returned `Bool` comes from the inner file flush rather than the queue flush step. -- For queued file sinks, this step may also be the point where queued records finally hit the inner file sink, so write-failure counters can change here even if earlier log calls only queued records. +- Queued file sinks first drain queued records, then flush the wrapped inner file sink. +- For queued file sinks, the returned `Bool` is `true` only when all queued records were consumed, the final file flush succeeded, and no new write, flush, or rotation failures were observed during that flush path. +- For queued file sinks, this step may also be the point where queued records finally hit the inner file sink, so failure counters can change here even if earlier log calls only queued records. - Non-file sinks return `false`. - This helper is narrower than generic `flush()` because it targets file sink behavior specifically. - After a file-backed configured logger has already cleared its file handle, later `file_flush()` calls return `false`. @@ -61,7 +61,7 @@ When code should branch on the outcome of a file flush: let ok = logger.file_flush() ``` -In this example, callers can distinguish file flush success from a non-file sink shape. +In this example, callers can distinguish file-specific flush success from a non-file sink shape. ### Error Case @@ -72,10 +72,12 @@ e.g.: - If callers want generic queue or sink advancement instead of file-specific behavior, `flush()` is the broader API. +- On queued file sinks, a `false` result may still mean queue consumption happened but file delivery observed a new failure. + ### Notes 1. Prefer this helper when the configured sink is known to be file-backed. -2. Queued file sinks may perform both queue flush and file flush work here, including surfacing delayed write failures from previously queued records. +2. Queued file sinks may perform both queue drain and file flush work here, including surfacing delayed failures from previously queued records. 3. Library or application facades derived from the same configured runtime logger still observe the same underlying file-flush availability state. diff --git a/docs/api/configured-logger-file-reopen.md b/docs/api/configured-logger-file-reopen.md index 821fd91..385722c 100644 --- a/docs/api/configured-logger-file-reopen.md +++ b/docs/api/configured-logger-file-reopen.md @@ -2,7 +2,7 @@ name: configured-logger-file-reopen group: api category: runtime -update-time: 20260512 +update-time: 20260707 description: Reopen the file sink behind a configured runtime logger with an optional append-mode override. key-word: - logger @@ -35,9 +35,10 @@ pub fn ConfiguredLogger::file_reopen(self : ConfiguredLogger, append~ : Bool? = Detailed rules explaining key parameters and behaviors - Plain file sinks reopen directly through the wrapped `RuntimeSink`. -- Queued file sinks forward reopen behavior to the wrapped inner file sink. +- Queued file sinks forward reopen behavior to the wrapped inner file sink only when no queued records are pending. - `append=None` preserves current reopen policy, while `Some(true/false)` overrides append mode. - Non-file sinks return `false`. +- If a queued file sink still has pending records, reopen is rejected and returns `false` so queued records are not later written under a different reopen mode than the one they were queued under. ### How to Use @@ -68,8 +69,10 @@ e.g.: - If callers only need the current configured policy, `file_reopen_with_current_policy()` may be the clearer API. +- If a queued file sink still has pending records, callers should flush or close it first before attempting reopen. + ### Notes 1. Use this helper for explicit recovery flows. -2. Pair it with `file_available()` and failure counters when diagnosing reopen behavior. +2. On queued file sinks, clear pending records first so reopen semantics stay stable for already queued writes. diff --git a/docs/api/configured-logger-file-reset-policy.md b/docs/api/configured-logger-file-reset-policy.md index ef44499..f77288e 100644 --- a/docs/api/configured-logger-file-reset-policy.md +++ b/docs/api/configured-logger-file-reset-policy.md @@ -2,8 +2,8 @@ name: configured-logger-file-reset-policy group: api category: runtime -update-time: 20260512 -description: Reset the runtime file policy of a configured file-backed logger back to its original defaults. +update-time: 20260707 +description: Reset the runtime file policy of a configured logger back to its captured defaults. key-word: - logger - runtime @@ -13,7 +13,7 @@ key-word: ## Configured-logger-file-reset-policy -Reset the runtime file policy of a `ConfiguredLogger` back to its original defaults. This helper restores append, auto-flush, and rotation policy together. +Reset the runtime file policy of a `ConfiguredLogger` back to its captured defaults. ### Interface @@ -21,56 +21,17 @@ Reset the runtime file policy of a `ConfiguredLogger` back to its original defau pub fn ConfiguredLogger::file_reset_policy(self : ConfiguredLogger) -> Bool {} ``` -#### input - -- `self : ConfiguredLogger` - Config-driven runtime logger whose file policy should be restored. - -#### output - -- `Bool` - Whether the reset was applied. - ### Explanation Detailed rules explaining key parameters and behaviors -- File-backed sinks restore their stored default file policy through the wrapped `RuntimeSink`. -- Queued file sinks forward the reset behavior to the wrapped inner file sink. +- File-backed sinks restore their runtime default policy through the wrapped `RuntimeSink`. +- Queued file sinks restore the wrapped inner file sink default policy only when no queued records are pending. - Non-file sinks return `false`. -- This helper is the inverse of runtime policy drift, not a generic reopen or flush action. - -### How to Use - -Here are some specific examples provided. - -#### When Need To Undo Runtime Policy Changes - -When file policy should return to the original configured defaults: -```moonbit -ignore(logger.file_reset_policy()) -``` - -In this example, append, auto-flush, and rotation settings are restored together. - -#### When Use Drift-aware Recovery - -When reset should only happen after runtime changes: -```moonbit -if !logger.file_policy_matches_default() { - ignore(logger.file_reset_policy()) -} -``` - -In this example, reset is only applied when runtime policy has diverged. - -### Error Case - -e.g.: -- If the configured sink is not file-backed, the method returns `false`. - -- If callers need to restore only one setting, a narrower setter may be more appropriate than a full policy reset. +- If a queued file sink still has pending records, the reset is rejected and returns `false` so already queued records are not later written under a different policy than the one they were queued under. ### Notes -1. Use this helper when the original bundled file policy should be restored intact. +1. Use this helper when runtime file policy should return to its captured defaults. -2. It pairs naturally with `file_policy_matches_default()` and `file_default_policy()`. +2. On queued file sinks, clear pending records first so policy mutation does not retroactively affect already queued writes. diff --git a/docs/api/configured-logger-file-set-append-mode.md b/docs/api/configured-logger-file-set-append-mode.md index 0d51a00..defa992 100644 --- a/docs/api/configured-logger-file-set-append-mode.md +++ b/docs/api/configured-logger-file-set-append-mode.md @@ -2,7 +2,7 @@ name: configured-logger-file-set-append-mode group: api category: runtime -update-time: 20260512 +update-time: 20260707 description: Update the append-mode policy used by the configured runtime file sink for later reopen behavior. key-word: - logger @@ -35,9 +35,10 @@ pub fn ConfiguredLogger::file_set_append_mode(self : ConfiguredLogger, append : Detailed rules explaining key parameters and behaviors - File-backed sinks update their stored append policy through the wrapped `RuntimeSink`. -- Queued file sinks forward the policy update to the wrapped inner file sink. +- Queued file sinks forward the policy update to the wrapped inner file sink only when no queued records are pending. - This helper updates policy only; it does not force immediate reopen. - Non-file sinks return `false`. +- If a queued file sink still has pending records, the update is rejected and returns `false` so already queued records are not later written under a different append policy than the one they were queued under. ### How to Use @@ -69,8 +70,10 @@ e.g.: - If callers need an immediate reopen as part of the same operation, one of the reopen helpers should be used afterward. +- If a queued file sink still has pending records, callers should flush or close it first before changing append mode. + ### Notes 1. This helper changes stored policy, not live file-handle state by itself. -2. It is useful when recovery logic wants to stage reopen behavior in advance. +2. On queued file sinks, clear pending records first so staged reopen policy does not retroactively affect already queued writes. diff --git a/docs/api/configured-logger-file-set-auto-flush.md b/docs/api/configured-logger-file-set-auto-flush.md index 2fb6ea6..2aef4ea 100644 --- a/docs/api/configured-logger-file-set-auto-flush.md +++ b/docs/api/configured-logger-file-set-auto-flush.md @@ -2,7 +2,7 @@ name: configured-logger-file-set-auto-flush group: api category: runtime -update-time: 20260512 +update-time: 20260707 description: Update the auto-flush policy used by the configured runtime file sink. key-word: - logger @@ -35,9 +35,10 @@ pub fn ConfiguredLogger::file_set_auto_flush(self : ConfiguredLogger, enabled : Detailed rules explaining key parameters and behaviors - File-backed sinks update their runtime auto-flush policy through the wrapped `RuntimeSink`. -- Queued file sinks forward the update to the wrapped inner file sink. +- Queued file sinks forward the update to the wrapped inner file sink only when no queued records are pending. - Non-file sinks return `false`. - This helper changes policy only; it does not itself flush pending data. +- If a queued file sink still has pending records, the update is rejected and returns `false` so already queued records are not later written under a different auto-flush policy than the one they were queued under. ### How to Use @@ -68,8 +69,10 @@ e.g.: - If callers need an immediate flush action, `file_flush()` is the operational API. +- If a queued file sink still has pending records, callers should flush or close it first before changing auto-flush policy. + ### Notes 1. Use this helper for runtime durability tuning. -2. Pair it with `file_auto_flush()` to verify the active policy. +2. On queued file sinks, clear pending records first so policy mutation does not retroactively affect already queued writes. diff --git a/docs/api/configured-logger-file-set-policy.md b/docs/api/configured-logger-file-set-policy.md index 0c5a0e6..dbd5809 100644 --- a/docs/api/configured-logger-file-set-policy.md +++ b/docs/api/configured-logger-file-set-policy.md @@ -2,7 +2,7 @@ name: configured-logger-file-set-policy group: api category: runtime -update-time: 20260512 +update-time: 20260707 description: Apply a bundled runtime file policy update to a configured file-backed logger. key-word: - logger @@ -35,9 +35,10 @@ pub fn ConfiguredLogger::file_set_policy(self : ConfiguredLogger, policy : FileS Detailed rules explaining key parameters and behaviors - File-backed sinks update append, auto-flush, and rotation together through the wrapped `RuntimeSink`. -- Queued file sinks forward the policy update to the wrapped inner file sink. +- Queued file sinks forward the policy update to the wrapped inner file sink only when no queued records are pending. - Non-file sinks return `false`. - This helper is broader than the single-setting setters because it updates the whole file policy in one call. +- If a queued file sink still has pending records, the update is rejected and returns `false` so already queued records are not later written under a different policy bundle than the one they were queued under. ### How to Use @@ -72,8 +73,10 @@ e.g.: - If callers only need to change one setting, a narrower setter such as `file_set_auto_flush(...)` or `file_set_rotation(...)` may be clearer. +- If a queued file sink still has pending records, callers should flush or close it first before changing policy. + ### Notes 1. Use this helper when the runtime policy should be treated as one cohesive object. -2. It pairs naturally with `file_policy()` and `file_default_policy()`. +2. On queued file sinks, clear pending records first so policy mutation does not retroactively affect already queued writes. diff --git a/docs/api/configured-logger-file-set-rotation.md b/docs/api/configured-logger-file-set-rotation.md index 51aace7..4dc6506 100644 --- a/docs/api/configured-logger-file-set-rotation.md +++ b/docs/api/configured-logger-file-set-rotation.md @@ -2,8 +2,8 @@ name: configured-logger-file-set-rotation group: api category: runtime -update-time: 20260512 -description: Update the rotation configuration used by the configured runtime file sink. +update-time: 20260707 +description: Update the rotation policy used by the configured runtime file sink. key-word: - logger - runtime @@ -13,21 +13,18 @@ key-word: ## Configured-logger-file-set-rotation -Update the rotation configuration used by a `ConfiguredLogger` file sink. This helper changes runtime file rotation behavior without rebuilding the logger. +Update the rotation policy used by a `ConfiguredLogger` file sink. ### Interface ```moonbit -pub fn ConfiguredLogger::file_set_rotation( - self : ConfiguredLogger, - rotation : FileRotation?, -) -> Bool {} +pub fn ConfiguredLogger::file_set_rotation(self : ConfiguredLogger, rotation : FileRotation?) -> Bool {} ``` #### input -- `self : ConfiguredLogger` - Config-driven runtime logger whose rotation policy should change. -- `rotation : FileRotation?` - New rotation config, or `None` to disable rotation. +- `self : ConfiguredLogger` - Config-driven runtime logger whose file rotation policy should change. +- `rotation : FileRotation?` - New runtime rotation policy. #### output @@ -38,41 +35,20 @@ pub fn ConfiguredLogger::file_set_rotation( Detailed rules explaining key parameters and behaviors - File-backed sinks update their runtime rotation policy through the wrapped `RuntimeSink`. -- Queued file sinks forward the update to the wrapped inner file sink. -- Passing `None` disables rotation. +- Queued file sinks forward the update to the wrapped inner file sink only when no queued records are pending. - Non-file sinks return `false`. - -### How to Use - -Here are some specific examples provided. - -#### When Need Runtime Rotation Tuning - -When a file sink should enable or change rotation dynamically: -```moonbit -ignore(logger.file_set_rotation(Some(file_rotation(1024, max_backups=3)))) -``` - -In this example, runtime rotation behavior is updated without rebuilding the logger. - -#### When Need To Disable Rotation - -When the file sink should stop rotating: -```moonbit -let ok = logger.file_set_rotation(None) -``` - -In this example, the runtime file sink has its rotation policy cleared explicitly. +- This helper changes policy only; it does not itself rotate or flush pending data. +- If a queued file sink still has pending records, the update is rejected and returns `false` so already queued records are not later written under a different rotation policy than the one they were queued under. ### Error Case e.g.: - If the configured sink is not file-backed, the method returns `false`. -- If callers only want to remove rotation, `file_clear_rotation()` is the more direct API. +- If a queued file sink still has pending records, callers should flush or close it first before changing rotation policy. ### Notes -1. Use this helper when setting a full runtime rotation config. +1. Use this helper when runtime rotation policy should change without rebuilding the logger. -2. It is useful for operational tuning without rebuilding the logger. +2. On queued file sinks, clear pending records first so policy mutation does not retroactively affect already queued writes. diff --git a/docs/api/configured-logger-flush-progress.md b/docs/api/configured-logger-flush-progress.md new file mode 100644 index 0000000..06e14d0 --- /dev/null +++ b/docs/api/configured-logger-flush-progress.md @@ -0,0 +1,78 @@ +--- +name: configured-logger-flush-progress +group: api +category: runtime +update-time: 20260707 +description: Return a structured generic flush progress snapshot for a ConfiguredLogger through RuntimeSink without collapsing queue and plain-file fallback semantics into one Int. +key-word: + - logger + - runtime + - flush + - public +--- + +## Configured-logger-flush-progress + +Return a structured generic flush progress snapshot for a `ConfiguredLogger`. This is the recommended configured runtime wrapper over `RuntimeSink::flush_progress(...)` when code wants truthful generic progress instead of the compatibility `Int` returned by `flush()`. + +### Interface + +```moonbit +pub fn ConfiguredLogger::flush_progress(self : ConfiguredLogger) -> RuntimeSinkProgress {} +``` + +#### input + +- `self : ConfiguredLogger` - Config-driven runtime logger whose generic flush progress should be observed. + +#### output + +- `RuntimeSinkProgress` - Structured progress snapshot returned by the wrapped `RuntimeSink::flush_progress(...)` call. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This helper delegates directly to `self.sink.flush_progress()`. +- Queue-wrapped sinks report queue advancement through `queue_advanced_count`. +- Plain file sinks report the generic fallback flush step through `file_flush_step_count`. +- Plain console-style sinks return a zeroed snapshot. +- This helper is the configured-logger entry point for the truthful generic progress surface introduced alongside the older compatibility `flush()` path. + +### How to Use + +Here are some specific examples provided. + +#### When Need Recommended Generic Flush Progress On A Config-built Logger + +When config-built runtime code should inspect flush progress explicitly: +```moonbit +let progress = logger.flush_progress() +``` + +In this example, the configured runtime logger reports structured progress without collapsing runtime-shape semantics. + +#### When Need To Branch On Queue-backed Versus Plain-file Generic Progress + +When application code should keep the config-built facade but still distinguish progress meaning: +```moonbit +let progress = logger.flush_progress() +if progress.queue_backed { + println(progress.queue_advanced_count) +} +``` + +In this example, queue advancement remains explicit even though the logger was built from config. + +### Error Case + +e.g.: +- If the configured runtime sink shape has no flushable state, the snapshot simply reports zero counts. + +- If callers need file-specific success semantics on a file-backed logger, `file_flush()` is the better API. + +### Notes + +1. Prefer `flush_progress()` over `flush()` in new configured-runtime code. + +2. `flush()` is still available for compatibility with older code that expects one numeric count. diff --git a/docs/api/configured-logger-flush.md b/docs/api/configured-logger-flush.md index e23f9d5..8129fb8 100644 --- a/docs/api/configured-logger-flush.md +++ b/docs/api/configured-logger-flush.md @@ -2,8 +2,8 @@ name: configured-logger-flush group: api category: runtime -update-time: 20260613 -description: Flush a configured runtime logger and return how many queued or file-backed operations were advanced through RuntimeSink. +update-time: 20260707 +description: Compatibility configured runtime flush helper that still returns one Int by collapsing generic queue progress and plain-file fallback steps. key-word: - logger - runtime @@ -13,7 +13,7 @@ key-word: ## Configured-logger-flush -Flush a `ConfiguredLogger` and return how much work was advanced. This is the configured logger wrapper over `RuntimeSink::flush(...)` for forcing queued or file-backed output to move forward after config-driven construction. +Flush a `ConfiguredLogger` and return one compatibility count. This helper is still available for older code, but new configured-runtime code should prefer `flush_progress()` because it exposes queue advancement and plain-file fallback steps separately. ### Interface @@ -27,16 +27,17 @@ pub fn ConfiguredLogger::flush(self : ConfiguredLogger) -> Int {} #### output -- `Int` - Count returned by the wrapped `RuntimeSink::flush(...)` call. +- `Int` - Compatibility count returned by the wrapped `RuntimeSink::flush(...)` call. ### Explanation Detailed rules explaining key parameters and behaviors - This helper delegates directly to `self.sink.flush()`. -- Queue-wrapped sinks forward to the concrete queue sink's `flush()` behavior. -- Plain file sinks call `FileSink::flush()` through `RuntimeSink` and convert the boolean result into `1` or `0`. -- Plain console-style sinks return `0` because they do not expose a meaningful buffered flush step here. +- Under the hood, `RuntimeSink::flush()` now rebuilds one compatibility count from `flush_progress()`. +- Queue-wrapped sinks still report queued-record consumption through that compatibility count. +- Plain file sinks still report the generic fallback flush step as `1` or `0`. +- Plain console-style sinks still return `0`. ### How to Use @@ -44,31 +45,37 @@ Here are some specific examples provided. #### When Need Explicit Queue Progress -When config-built queue output should be advanced manually: +When older code already expects one numeric flush count from a config-built logger: ```moonbit ignore(logger.flush()) ``` -In this example, the configured runtime logger is flushed without reaching into the sink directly. +In this example, the configured runtime logger is flushed without changing the legacy return shape. #### When Need A Post-write Flush Barrier -When a service wants stronger delivery behavior after a burst of writes: +When code only needs a coarse non-zero check and does not care which runtime dimension advanced: ```moonbit let flushed = logger.flush() ``` -In this example, callers can observe how much work was advanced by the flush request. +In this example, callers still get one compatibility count rather than a structured progress snapshot. ### Error Case e.g.: - If the configured runtime sink shape has no flushable state, the method may simply return `0`. -- If callers need bounded manual draining rather than generic flush behavior, `drain(...)` is the better API. +- If callers need truthful generic progress semantics, `flush_progress()` is the better API. + +- If callers need bounded manual draining rather than generic flush behavior, `drain_progress(...)` is usually the better API. + +- If callers need file-specific success semantics on a file-backed logger, `file_flush()` is the better API. ### Notes -1. Use this helper after config-driven logger construction when explicit runtime flushing matters. +1. Treat this method as a compatibility helper for older numeric code. -2. The exact return value depends on which `RuntimeSink` variant the configured logger owns. +2. Prefer `flush_progress()` in new configured-runtime code. + +3. The exact return value depends on which `RuntimeSink` variant the configured logger owns. diff --git a/docs/api/configured-logger.md b/docs/api/configured-logger.md index d52f5f2..93a17b1 100644 --- a/docs/api/configured-logger.md +++ b/docs/api/configured-logger.md @@ -2,7 +2,7 @@ name: configured-logger group: api category: runtime -update-time: 20260613 +update-time: 20260707 description: Public configured runtime logger alias used for config-built sync logging with queue and file controls. key-word: - logger @@ -33,7 +33,8 @@ Detailed rules explaining key parameters and behaviors - It preserves normal logger methods such as `info(...)`, `warn(...)`, `error(...)`, and the other `Logger` APIs. - Because it is `Logger[RuntimeSink]`, it also keeps ordinary logger composition and target behavior such as `with_target(...)`, `child(...)`, and per-call `log(..., target=...)` overrides. - In particular, `log(..., target=...)` can override the target for one call, while severity helpers such as `info(...)`, `warn(...)`, and `error(...)` continue using the stored logger target unless code derives another logger first with `with_target(...)` or `child(...)`. -- It also exposes configured runtime helpers such as `flush()`, `drain()`, `pending_count()`, `dropped_count()`, and file-specific controls when the runtime sink supports them. +- It also exposes configured runtime helpers such as `flush_progress()`, `drain_progress()`, `flush()`, `drain()`, `pending_count()`, `dropped_count()`, and file-specific controls when the runtime sink supports them. +- `flush_progress()` and `drain_progress()` are the recommended truthful generic progress helpers, while `flush()` and `drain()` remain compatibility wrappers that collapse the structured result back into one `Int`. - Because `ConfiguredLogger` is only an alias over `Logger[RuntimeSink]`, ordinary sync composition helpers such as `with_target(...)`, `child(...)`, `with_timestamp(...)`, `with_filter(...)`, and `with_patch(...)` keep the same visible runtime-sink logger line rather than stripping away the configured helper surface. - In current direct builder coverage, derived configured loggers still preserve queue counters, drain or flush behavior, runtime sink variant choice, and file helper access instead of collapsing back to a narrower non-runtime shape. - Builders such as `build_logger(...)` and `parse_and_build_logger(...)` return this alias as the main sync config-to-runtime result. diff --git a/docs/api/runtime-sink-close.md b/docs/api/runtime-sink-close.md index 9c18423..1520567 100644 --- a/docs/api/runtime-sink-close.md +++ b/docs/api/runtime-sink-close.md @@ -2,8 +2,8 @@ name: runtime-sink-close group: api category: runtime -update-time: 20260613 -description: Close a RuntimeSink and report whether the underlying sink performed a successful close action. +update-time: 20260707 +description: Close a RuntimeSink and report whether the concrete close path succeeded. key-word: - runtime - sink @@ -27,7 +27,7 @@ pub fn RuntimeSink::close(self : RuntimeSink) -> Bool { #### output -- `Bool` - Whether the concrete runtime sink reported a successful close action. +- `Bool` - Whether the concrete runtime sink reported a successful close path. ### Explanation @@ -35,9 +35,11 @@ Detailed rules explaining key parameters and behaviors - Plain console-style runtime sinks return `true` because they do not have a meaningful close step here. - Plain file runtime sinks forward directly to `FileSink::close()`. -- Queued file runtime sinks close the wrapped file sink rather than only the queue wrapper. -- Generic `close()` on `QueuedFile` does not drain or flush queued records first; it closes the inner file sink directly. -- Queue-wrapped console-style runtime sinks return `true` as a no-op success. +- Queued file runtime sinks now follow the same safe teardown path as `file_close()`: they first try to drain the queue, then flush the wrapped file sink, then close it. +- On `QueuedFile`, the returned `Bool` is `true` only when that whole teardown path succeeds without introducing new file failures. +- Queue-wrapped console-style runtime sinks also use drain-first teardown. +- For `QueuedConsole`, `QueuedJsonConsole`, and `QueuedTextConsole`, `close()` consumes pending queue items before reporting success. +- Because these wrapped console-style sinks do not expose an additional close-failure channel, success for these variants means the backlog was drained to zero. - This method is the direct sink-level API used by `ConfiguredLogger::close(...)`. - For file-backed runtime sinks, later `close()` calls return `false` after the handle has already been cleared. @@ -72,10 +74,14 @@ e.g.: - If callers know they are working with a direct `FileSink`, `FileSink::close()` is the narrower API. +- On queued file sinks, `true` still does not mean the records are guaranteed to be durable beyond what the current backend can report; it means the queue-drain, file-flush, and file-close path completed without a newly observed file failure. + +- On queued non-file sinks, `true` means the queued backlog was consumed before teardown completed. + ### Notes 1. Use this helper when code is managing a `RuntimeSink` value directly. -2. Use `file_close()` instead of generic `close()` when queued file sinks should flush pending records before file teardown. +2. Generic `close()` is now safe for queue-backed runtime sinks and no longer skips queued records silently. 3. `ConfiguredLogger::close(...)` is the higher-level wrapper for config-built loggers. diff --git a/docs/api/runtime-sink-drain-progress.md b/docs/api/runtime-sink-drain-progress.md new file mode 100644 index 0000000..b66c38b --- /dev/null +++ b/docs/api/runtime-sink-drain-progress.md @@ -0,0 +1,80 @@ +--- +name: runtime-sink-drain-progress +group: api +category: runtime +update-time: 20260707 +description: Return a structured generic drain progress snapshot for a RuntimeSink without collapsing queue and plain-file fallback semantics into one Int. +key-word: + - runtime + - sink + - drain + - public +--- + +## Runtime-sink-drain-progress + +Return a structured generic drain progress snapshot for a `RuntimeSink`. This is the recommended truthful generic runtime drain helper when callers need bounded or full queue progress without relying on the compatibility `Int` returned by `drain()`. + +### Interface + +```moonbit +pub fn RuntimeSink::drain_progress( + self : RuntimeSink, + max_items~ : Int = -1, +) -> RuntimeSinkProgress { +``` + +#### input + +- `self : RuntimeSink` - Runtime sink whose generic drain progress should be observed. +- `max_items : Int` - Optional upper bound on drained queued items. Negative values mean no explicit bound. + +#### output + +- `RuntimeSinkProgress` - Structured progress snapshot separating queue advancement from plain-file flush fallback steps. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- Queue-wrapped runtime sinks report consumed queued items through `queue_advanced_count` and honor `max_items`. +- Plain file runtime sinks still follow the generic fallback path and report `FileSink::flush()` as `file_flush_step_count` `1` or `0`. +- Plain console-style runtime sinks return a zeroed snapshot because they do not own a drainable queue here. +- Queued file runtime sinks report queue advancement, while delayed file delivery failures still belong to file failure counters and `file_flush()`. +- This helper preserves the old runtime behavior but makes the meaning explicit in the result shape. +- `drain()` remains available as the legacy convenience wrapper that sums the fields back into one count. + +### How to Use + +Here are some specific examples provided. + +#### When Need Recommended Bounded Generic Drain Progress + +When code should observe one bounded drain step without mixing units: +```moonbit +let progress = sink.drain_progress(max_items=16) +``` + +In this example, queue progress and plain-file fallback stay separated. + +#### When Need A Full Manual Generic Drain Snapshot + +When support code should empty queued work and keep runtime-shape context: +```moonbit +let progress = sink.drain_progress() +``` + +In this example, the caller can inspect both the count and the runtime shape afterwards. + +### Error Case + +e.g.: +- If the runtime sink is not queue-backed, the snapshot may stay zeroed or use the plain-file fallback field. + +- If callers want file-specific success semantics after queue delivery, `file_flush()` is the better API. + +### Notes + +1. Prefer `drain_progress()` over `drain()` in new generic runtime code. + +2. Use `pending_count()` together with this helper when remaining backlog must also be observed. diff --git a/docs/api/runtime-sink-drain.md b/docs/api/runtime-sink-drain.md index 8e1a5eb..7c0655b 100644 --- a/docs/api/runtime-sink-drain.md +++ b/docs/api/runtime-sink-drain.md @@ -2,8 +2,8 @@ name: runtime-sink-drain group: api category: runtime -update-time: 20260613 -description: Drain queued work from a RuntimeSink with an optional item limit. +update-time: 20260707 +description: Compatibility RuntimeSink drain helper that still returns one Int by collapsing generic queue progress and plain-file fallback steps. key-word: - runtime - sink @@ -13,7 +13,7 @@ key-word: ## Runtime-sink-drain -Drain queued work from a `RuntimeSink`. This helper is useful when code owns a runtime sink directly and needs controlled queue progress. +Drain queued work from a `RuntimeSink` and return one compatibility count. This helper is still available for older code, but new generic runtime code should prefer `drain_progress()` because it exposes queue advancement and plain-file fallback steps separately. ### Interface @@ -28,16 +28,18 @@ pub fn RuntimeSink::drain(self : RuntimeSink, max_items~ : Int = -1) -> Int { #### output -- `Int` - Number of drained items, or the fallback flush count for plain file sinks. +- `Int` - Compatibility count produced from the structured `drain_progress()` result. ### Explanation Detailed rules explaining key parameters and behaviors -- Queue-wrapped runtime sinks forward to the wrapped queue sink's `drain(...)` behavior. -- Plain file runtime sinks fall back to `FileSink::flush()` behavior and return `1` or `0`. -- Plain console-style runtime sinks return `0` because they do not own a drainable queue. -- This method is the direct sink-level API used by `ConfiguredLogger::drain(...)`. +- This method now delegates to `drain_progress()` and sums `queue_advanced_count + file_flush_step_count` back into one compatibility number. +- Queue-wrapped runtime sinks still report how many queued records were consumed during the drain. +- A queued file drain can still return a positive number even when file failure counters increase during the same queue-delivery step. +- Plain file runtime sinks still use the generic `FileSink::flush()` fallback and therefore still return `1` or `0`. +- Plain console-style runtime sinks still return `0` because the structured result stays zeroed. +- This method remains the direct sink-level API used by `ConfiguredLogger::drain(...)`. ### How to Use @@ -45,31 +47,37 @@ Here are some specific examples provided. #### When Need Bounded Queue Progress -When direct queue-backed runtime work should be advanced in chunks: +When older code already expects one numeric drain count: ```moonbit let drained = sink.drain(max_items=16) ``` -In this example, callers cap how much queued work is processed in one step. +In this example, callers still cap how much queued work is processed in one step while keeping the legacy return shape. #### When Need Full Manual Drain -When a runtime queue should be emptied without an explicit item cap: +When code should keep the older full-drain compatibility path: ```moonbit ignore(sink.drain()) ``` -In this example, the runtime sink drains as much queued work as its concrete variant allows. +In this example, the runtime sink drains as much queued work as its concrete variant allows while still returning one numeric count. ### Error Case e.g.: - If the runtime sink is not queue-backed, the result may be `0` or file-flush fallback behavior. -- If callers only need generic flush semantics, `flush()` may be the simpler API. +- If callers need truthful generic progress semantics, `drain_progress()` is the better API. + +- If callers only need generic flush semantics, `flush_progress()` may be the simpler structured API. + +- If callers need file-specific success semantics after draining a queued file sink, they should inspect failure counters or use `file_flush()` for the file-specific path. ### Notes -1. Prefer this helper when queue progress should be bounded or directly observed. +1. Treat this method as a compatibility helper for older numeric code. -2. `ConfiguredLogger::drain(...)` is the higher-level wrapper for config-built loggers. +2. Prefer `drain_progress()` in new generic runtime code. + +3. `ConfiguredLogger::drain(...)` is the higher-level wrapper for config-built loggers. diff --git a/docs/api/runtime-sink-file-clear-rotation.md b/docs/api/runtime-sink-file-clear-rotation.md index adb5fb4..8235072 100644 --- a/docs/api/runtime-sink-file-clear-rotation.md +++ b/docs/api/runtime-sink-file-clear-rotation.md @@ -2,8 +2,8 @@ name: runtime-sink-file-clear-rotation group: api category: runtime -update-time: 20260613 -description: Disable runtime rotation on a file-backed RuntimeSink. +update-time: 20260707 +description: Clear the rotation policy used by a file-backed RuntimeSink. key-word: - runtime - sink @@ -13,7 +13,7 @@ key-word: ## Runtime-sink-file-clear-rotation -Disable runtime rotation on a file-backed `RuntimeSink`. This helper is the direct shortcut for clearing rotation policy from a runtime sink value. +Clear the rotation policy used by a file-backed `RuntimeSink`. ### Interface @@ -23,7 +23,7 @@ pub fn RuntimeSink::file_clear_rotation(self : RuntimeSink) -> Bool { #### input -- `self : RuntimeSink` - Runtime sink whose rotation policy should be cleared. +- `self : RuntimeSink` - Runtime sink whose file rotation policy should be cleared. #### output @@ -33,42 +33,13 @@ pub fn RuntimeSink::file_clear_rotation(self : RuntimeSink) -> Bool { Detailed rules explaining key parameters and behaviors -- Plain `File` runtime variants clear rotation on the wrapped `FileSink` and return `true`. -- `QueuedFile` runtime variants forward the update to the wrapped inner `FileSink` and return `true`. +- Plain `File` runtime variants clear the wrapped `FileSink` rotation policy and return `true`. +- `QueuedFile` runtime variants clear the wrapped inner `FileSink` rotation policy only when no queued records are pending. - Non-file runtime variants return `false`. -- This helper is equivalent in intent to setting rotation to `None`, but is clearer at the call site. - -### How to Use - -Here are some specific examples provided. - -#### When Need To Disable Rotation Explicitly - -When runtime file rotation should be turned off on a direct sink value: -```moonbit -ignore(sink.file_clear_rotation()) -``` - -In this example, rotation policy is removed directly. - -#### When Need A Clear Intent Shortcut - -When code should make the disable-rotation intent obvious: -```moonbit -let ok = sink.file_clear_rotation() -``` - -In this example, the call site reads more clearly than a generic config setter. - -### Error Case - -e.g.: -- If the runtime sink is not file-backed, the method returns `false`. - -- If callers need to switch to another rotation config rather than disable rotation, `file_set_rotation(...)` is the better API. +- If a queued file sink still has pending records, the update is rejected and returns `false` so already queued records are not later written under a different rotation policy than the one they were queued under. ### Notes -1. Use this helper when the desired effect is simply `rotation off`. +1. Use this helper when runtime rotation policy should be removed without rebuilding the sink. -2. It is clearer than passing `None` through a broader setter when intent matters. +2. On queued file sinks, clear pending records first so policy mutation does not retroactively affect already queued writes. diff --git a/docs/api/runtime-sink-file-close.md b/docs/api/runtime-sink-file-close.md index f4a5529..641fb3d 100644 --- a/docs/api/runtime-sink-file-close.md +++ b/docs/api/runtime-sink-file-close.md @@ -2,8 +2,8 @@ name: runtime-sink-file-close group: api category: runtime -update-time: 20260613 -description: Close the file sink behind a RuntimeSink when one is present. +update-time: 20260707 +description: Close the file sink behind a RuntimeSink when one is present, with queued-file success tied to safe drain-flush-close behavior. key-word: - runtime - sink @@ -27,15 +27,15 @@ pub fn RuntimeSink::file_close(self : RuntimeSink) -> Bool { #### output -- `Bool` - Whether the underlying file close succeeded. +- `Bool` - Whether the file-specific close path succeeded. ### Explanation Detailed rules explaining key parameters and behaviors - Plain `File` runtime variants forward directly to `FileSink::close()`. -- `QueuedFile` runtime variants first attempt `sink.flush()` on the queue wrapper, then call `sink.sink.close()` on the wrapped file sink. -- For `QueuedFile`, the queue flush result is ignored and the returned `Bool` comes from the inner file close. +- `QueuedFile` runtime variants first drain the queue, then flush the wrapped file sink, then close it. +- For `QueuedFile`, the returned `Bool` is `true` only when that whole path succeeds and no new write, flush, or rotation failures are observed during the drain-flush-close step. - Non-file runtime variants return `false`. - After a file-backed runtime sink has already cleared its handle, later `file_close()` calls return `false`. @@ -59,7 +59,7 @@ When application code wants the direct file close outcome: let closed = sink.file_close() ``` -In this example, the result describes file close behavior rather than generic sink close behavior. +In this example, the result describes the file-specific close path rather than generic sink close behavior. ### Error Case @@ -70,8 +70,10 @@ e.g.: - If callers only need generic sink teardown, `close()` is the broader API. +- On queued file sinks, `true` still does not mean a stronger durability contract than the current backend can report; it means the safe drain-flush-close path completed without a newly observed file failure. + ### Notes 1. Prefer this helper when direct runtime code specifically cares about file-backed shutdown. -2. Queued file sinks flush pending records before closing the file, unlike generic `close()`. +2. Generic `close()` now uses the same safe queued-file teardown path. diff --git a/docs/api/runtime-sink-file-flush.md b/docs/api/runtime-sink-file-flush.md index 3950727..6f33d74 100644 --- a/docs/api/runtime-sink-file-flush.md +++ b/docs/api/runtime-sink-file-flush.md @@ -2,8 +2,8 @@ name: runtime-sink-file-flush group: api category: runtime -update-time: 20260614 -description: Flush the file sink behind a RuntimeSink when one is present. +update-time: 20260707 +description: Flush the file sink behind a RuntimeSink when one is present, with queued-file success tied to both queue drain and file flush outcome. key-word: - runtime - sink @@ -27,16 +27,16 @@ pub fn RuntimeSink::file_flush(self : RuntimeSink) -> Bool { #### output -- `Bool` - Whether the underlying file flush succeeded. +- `Bool` - Whether the file-specific flush path succeeded. ### Explanation Detailed rules explaining key parameters and behaviors - Plain `File` runtime variants forward directly to `FileSink::flush()`. -- `QueuedFile` runtime variants first attempt `sink.flush()` on the queue wrapper, then call `sink.sink.flush()` on the wrapped file sink. -- For `QueuedFile`, the queue flush result is ignored and the returned `Bool` comes from the inner file flush. -- For `QueuedFile`, this step may also be the point where queued records finally reach the inner file sink, so write-failure counters can change here even if earlier `log(...)` calls only enqueued records. +- `QueuedFile` runtime variants first drain the queue, then flush the wrapped file sink. +- For `QueuedFile`, the returned `Bool` is `true` only when all queued records were consumed, the final file flush succeeded, and no new write, flush, or rotation failures were observed during that flush path. +- For `QueuedFile`, this step may also be the point where queued records finally reach the inner file sink, so failure counters can change here even if earlier `log(...)` calls only enqueued records. - Non-file runtime variants return `false`. - After a file-backed runtime sink has already cleared its handle, later `file_flush()` calls return `false`. @@ -60,7 +60,7 @@ When code should branch on the outcome of a direct file flush: let ok = sink.file_flush() ``` -In this example, callers can distinguish file flush success from a non-file sink shape. +In this example, callers can distinguish file-specific flush success from a non-file sink shape. ### Error Case @@ -71,10 +71,12 @@ e.g.: - If callers want generic queue or sink advancement instead of file-specific behavior, `flush()` is the broader API. +- On queued file sinks, a `false` result may mean queue consumption happened but file delivery still observed a new failure. + ### Notes 1. Prefer this helper when direct runtime code specifically cares about file flush behavior. -2. Queued file sinks may perform both queue flush work and file flush work here, including surfacing delayed write failures from previously queued records. +2. Queued file sinks may perform both queue drain work and file flush work here, including surfacing delayed failures from previously queued records. 3. Library or application facades that share the same wrapped file-backed runtime sink still observe the same flush availability state. diff --git a/docs/api/runtime-sink-file-reopen.md b/docs/api/runtime-sink-file-reopen.md index 94f76f1..3b6a005 100644 --- a/docs/api/runtime-sink-file-reopen.md +++ b/docs/api/runtime-sink-file-reopen.md @@ -2,7 +2,7 @@ name: runtime-sink-file-reopen group: api category: runtime -update-time: 20260613 +update-time: 20260707 description: Reopen the file sink behind a RuntimeSink with an optional append-mode override. key-word: - runtime @@ -35,9 +35,10 @@ pub fn RuntimeSink::file_reopen(self : RuntimeSink, append~ : Bool? = None) -> B Detailed rules explaining key parameters and behaviors - Plain `File` runtime variants reopen directly. -- `QueuedFile` runtime variants forward reopen behavior to the wrapped inner file sink. +- `QueuedFile` runtime variants forward reopen behavior to the wrapped inner file sink only when no queued records are pending. - `append=None` preserves current reopen policy, while `Some(true/false)` overrides append mode. - Non-file runtime variants return `false`. +- If a queued file sink still has pending records, reopen is rejected and returns `false` so queued records are not later written under a different reopen mode than the one they were queued under. ### How to Use @@ -68,8 +69,10 @@ e.g.: - If callers only need the current configured policy, `file_reopen_with_current_policy()` may be the clearer API. +- If a queued file sink still has pending records, callers should flush or close it first before attempting reopen. + ### Notes 1. Use this helper for explicit direct recovery flows on `RuntimeSink` values. -2. Pair it with `file_available()` and failure counters when diagnosing reopen behavior. +2. On queued file sinks, clear pending records first so reopen semantics stay stable for already queued writes. diff --git a/docs/api/runtime-sink-file-reset-policy.md b/docs/api/runtime-sink-file-reset-policy.md index 268af66..3e7377e 100644 --- a/docs/api/runtime-sink-file-reset-policy.md +++ b/docs/api/runtime-sink-file-reset-policy.md @@ -2,8 +2,8 @@ name: runtime-sink-file-reset-policy group: api category: runtime -update-time: 20260613 -description: Reset the runtime file policy of a file-backed RuntimeSink back to its original defaults. +update-time: 20260707 +description: Reset the runtime file policy of a RuntimeSink back to its captured defaults. key-word: - runtime - sink @@ -13,7 +13,7 @@ key-word: ## Runtime-sink-file-reset-policy -Reset the runtime file policy of a `RuntimeSink` back to its original defaults. This helper restores append, auto-flush, and rotation policy together on direct sink values. +Reset the runtime file policy of a `RuntimeSink` back to its captured defaults. ### Interface @@ -21,56 +21,17 @@ Reset the runtime file policy of a `RuntimeSink` back to its original defaults. pub fn RuntimeSink::file_reset_policy(self : RuntimeSink) -> Bool { ``` -#### input - -- `self : RuntimeSink` - Runtime sink whose file policy should be restored. - -#### output - -- `Bool` - Whether the reset was applied. - ### Explanation Detailed rules explaining key parameters and behaviors -- Plain `File` runtime variants restore their stored default file policy and return `true`. -- `QueuedFile` runtime variants forward the reset behavior to the wrapped inner `FileSink` and return `true`. +- Plain `File` runtime variants restore the wrapped `FileSink` default policy and return `true`. +- `QueuedFile` runtime variants restore the wrapped inner `FileSink` default policy only when no queued records are pending. - Non-file runtime variants return `false`. -- This helper is the inverse of runtime policy drift, not a generic reopen or flush action. - -### How to Use - -Here are some specific examples provided. - -#### When Need To Undo Runtime Policy Changes - -When file policy should return to the original defaults captured by the runtime sink: -```moonbit -ignore(sink.file_reset_policy()) -``` - -In this example, append, auto-flush, and rotation settings are restored together. - -#### When Use Drift-aware Recovery - -When reset should only happen after runtime changes: -```moonbit -if !sink.file_policy_matches_default() { - ignore(sink.file_reset_policy()) -} -``` - -In this example, reset is only applied when runtime policy has diverged. - -### Error Case - -e.g.: -- If the runtime sink is not file-backed, the method returns `false`. - -- If callers need to restore only one setting, a narrower setter may be more appropriate than a full policy reset. +- If a queued file sink still has pending records, the reset is rejected and returns `false` so already queued records are not later written under a different policy than the one they were queued under. ### Notes -1. Use this helper when the original bundled file policy should be restored intact. +1. Use this helper when runtime file policy should return to its captured defaults. -2. It pairs naturally with `file_policy_matches_default()` and `file_default_policy()`. +2. On queued file sinks, clear pending records first so policy mutation does not retroactively affect already queued writes. diff --git a/docs/api/runtime-sink-file-set-append-mode.md b/docs/api/runtime-sink-file-set-append-mode.md index d52a855..7d6a1c5 100644 --- a/docs/api/runtime-sink-file-set-append-mode.md +++ b/docs/api/runtime-sink-file-set-append-mode.md @@ -2,7 +2,7 @@ name: runtime-sink-file-set-append-mode group: api category: runtime -update-time: 20260613 +update-time: 20260707 description: Update the append-mode policy used by a file-backed RuntimeSink for later reopen behavior. key-word: - runtime @@ -35,9 +35,10 @@ pub fn RuntimeSink::file_set_append_mode(self : RuntimeSink, append : Bool) -> B Detailed rules explaining key parameters and behaviors - Plain `File` runtime variants update their stored append policy and return `true`. -- `QueuedFile` runtime variants forward the policy update to the wrapped inner `FileSink` and return `true`. +- `QueuedFile` runtime variants forward the policy update to the wrapped inner `FileSink` only when no queued records are pending. - This helper updates policy only; it does not force immediate reopen. - Non-file runtime variants return `false`. +- If a queued file sink still has pending records, the update is rejected and returns `false` so already queued records are not later written under a different append policy than the one they were queued under. ### How to Use @@ -69,8 +70,10 @@ e.g.: - If callers need an immediate reopen as part of the same operation, one of the reopen helpers should be used afterward. +- If a queued file sink still has pending records, callers should flush or close it first before changing append mode. + ### Notes 1. This helper changes stored policy, not live file-handle state by itself. -2. It is useful when recovery logic wants to stage reopen behavior in advance. +2. On queued file sinks, clear pending records first so staged reopen policy does not retroactively affect already queued writes. diff --git a/docs/api/runtime-sink-file-set-auto-flush.md b/docs/api/runtime-sink-file-set-auto-flush.md index 81eab87..19d9139 100644 --- a/docs/api/runtime-sink-file-set-auto-flush.md +++ b/docs/api/runtime-sink-file-set-auto-flush.md @@ -2,7 +2,7 @@ name: runtime-sink-file-set-auto-flush group: api category: runtime -update-time: 20260613 +update-time: 20260707 description: Update the auto-flush policy used by a file-backed RuntimeSink. key-word: - runtime @@ -35,9 +35,10 @@ pub fn RuntimeSink::file_set_auto_flush(self : RuntimeSink, enabled : Bool) -> B Detailed rules explaining key parameters and behaviors - Plain `File` runtime variants update the wrapped `FileSink` auto-flush policy and return `true`. -- `QueuedFile` runtime variants forward the update to the wrapped inner `FileSink` and return `true`. +- `QueuedFile` runtime variants forward the update to the wrapped inner `FileSink` only when no queued records are pending. - Non-file runtime variants return `false`. - This helper changes policy only; it does not itself flush pending data. +- If a queued file sink still has pending records, the update is rejected and returns `false` so already queued records are not later written under a different auto-flush policy than the one they were queued under. ### How to Use @@ -68,8 +69,10 @@ e.g.: - If callers need an immediate flush action, `file_flush()` is the operational API. +- If a queued file sink still has pending records, callers should flush or close it first before changing auto-flush policy. + ### Notes 1. Use this helper for direct runtime durability tuning on `RuntimeSink` values. -2. Pair it with `file_auto_flush()` to verify the active policy. +2. On queued file sinks, clear pending records first so policy mutation does not retroactively affect already queued writes. diff --git a/docs/api/runtime-sink-file-set-policy.md b/docs/api/runtime-sink-file-set-policy.md index 4a28fb2..916d8d6 100644 --- a/docs/api/runtime-sink-file-set-policy.md +++ b/docs/api/runtime-sink-file-set-policy.md @@ -2,7 +2,7 @@ name: runtime-sink-file-set-policy group: api category: runtime -update-time: 20260613 +update-time: 20260707 description: Apply a bundled runtime file policy update to a file-backed RuntimeSink. key-word: - runtime @@ -35,9 +35,10 @@ pub fn RuntimeSink::file_set_policy(self : RuntimeSink, policy : FileSinkPolicy) Detailed rules explaining key parameters and behaviors - Plain `File` runtime variants update append, auto-flush, and rotation together on the wrapped `FileSink` and return `true`. -- `QueuedFile` runtime variants forward the policy update to the wrapped inner `FileSink` and return `true`. +- `QueuedFile` runtime variants forward the policy update to the wrapped inner `FileSink` only when no queued records are pending. - Non-file runtime variants return `false`. - This helper is broader than the single-setting setters because it updates the whole file policy in one call. +- If a queued file sink still has pending records, the update is rejected and returns `false` so already queued records are not later written under a different policy bundle than the one they were queued under. ### How to Use @@ -72,8 +73,10 @@ e.g.: - If callers only need to change one setting, a narrower setter such as `file_set_auto_flush(...)` or `file_set_rotation(...)` may be clearer. +- If a queued file sink still has pending records, callers should flush or close it first before changing policy. + ### Notes 1. Use this helper when the runtime policy should be treated as one cohesive object. -2. It pairs naturally with `file_policy()` and `file_default_policy()`. +2. On queued file sinks, clear pending records first so policy mutation does not retroactively affect already queued writes. diff --git a/docs/api/runtime-sink-file-set-rotation.md b/docs/api/runtime-sink-file-set-rotation.md index fa5706f..2e5369c 100644 --- a/docs/api/runtime-sink-file-set-rotation.md +++ b/docs/api/runtime-sink-file-set-rotation.md @@ -2,8 +2,8 @@ name: runtime-sink-file-set-rotation group: api category: runtime -update-time: 20260613 -description: Update the rotation configuration used by a file-backed RuntimeSink. +update-time: 20260707 +description: Update the rotation policy used by a file-backed RuntimeSink. key-word: - runtime - sink @@ -13,7 +13,7 @@ key-word: ## Runtime-sink-file-set-rotation -Update the rotation configuration used by a file-backed `RuntimeSink`. This helper changes direct runtime file rotation behavior without rebuilding or rewrapping the sink. +Update the rotation policy used by a file-backed `RuntimeSink`. ### Interface @@ -23,8 +23,8 @@ pub fn RuntimeSink::file_set_rotation(self : RuntimeSink, rotation : FileRotatio #### input -- `self : RuntimeSink` - Runtime sink whose rotation policy should change. -- `rotation : FileRotation?` - New rotation config, or `None` to disable rotation. +- `self : RuntimeSink` - Runtime sink whose file rotation policy should change. +- `rotation : FileRotation?` - New runtime rotation policy. #### output @@ -35,41 +35,20 @@ pub fn RuntimeSink::file_set_rotation(self : RuntimeSink, rotation : FileRotatio Detailed rules explaining key parameters and behaviors - Plain `File` runtime variants update the wrapped `FileSink` rotation policy and return `true`. -- `QueuedFile` runtime variants forward the update to the wrapped inner `FileSink` and return `true`. -- Passing `None` disables rotation. +- `QueuedFile` runtime variants forward the update to the wrapped inner `FileSink` only when no queued records are pending. - Non-file runtime variants return `false`. - -### How to Use - -Here are some specific examples provided. - -#### When Need Direct Runtime Rotation Tuning - -When a file-backed runtime sink should enable or change rotation dynamically: -```moonbit -ignore(sink.file_set_rotation(Some(file_rotation(1024, max_backups=3)))) -``` - -In this example, runtime rotation behavior is updated without rebuilding the sink. - -#### When Need To Disable Rotation Through The Setter - -When the file sink should stop rotating through one general update path: -```moonbit -let ok = sink.file_set_rotation(None) -``` - -In this example, the direct runtime file sink has its rotation policy cleared explicitly. +- This helper changes policy only; it does not itself rotate or flush pending data. +- If a queued file sink still has pending records, the update is rejected and returns `false` so already queued records are not later written under a different rotation policy than the one they were queued under. ### Error Case e.g.: - If the runtime sink is not file-backed, the method returns `false`. -- If callers only want to remove rotation, `file_clear_rotation()` is the more direct API. +- If a queued file sink still has pending records, callers should flush or close it first before changing rotation policy. ### Notes -1. Use this helper when setting a full direct runtime rotation config. +1. Use this helper when runtime rotation policy should change without rebuilding the sink. -2. It is useful for operational tuning without rebuilding the sink. +2. On queued file sinks, clear pending records first so policy mutation does not retroactively affect already queued writes. diff --git a/docs/api/runtime-sink-flush-progress.md b/docs/api/runtime-sink-flush-progress.md new file mode 100644 index 0000000..cd5393b --- /dev/null +++ b/docs/api/runtime-sink-flush-progress.md @@ -0,0 +1,79 @@ +--- +name: runtime-sink-flush-progress +group: api +category: runtime +update-time: 20260707 +description: Return a structured generic flush progress snapshot for a RuntimeSink without collapsing queue and plain-file fallback semantics into one Int. +key-word: + - runtime + - sink + - flush + - public +--- + +## Runtime-sink-flush-progress + +Return a structured generic flush progress snapshot for a `RuntimeSink`. This is the recommended truthful generic runtime flush helper when callers need to observe progress without relying on the compatibility `Int` returned by `flush()`. + +### Interface + +```moonbit +pub fn RuntimeSink::flush_progress(self : RuntimeSink) -> RuntimeSinkProgress { +``` + +#### input + +- `self : RuntimeSink` - Runtime sink whose generic flush progress should be observed. + +#### output + +- `RuntimeSinkProgress` - Structured progress snapshot separating queue advancement from plain-file flush fallback steps. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- Plain console-style runtime sinks return a zeroed snapshot with `queue_backed=false` and `file_backed=false`. +- Plain file runtime sinks call `FileSink::flush()` and report the fallback result through `file_flush_step_count` as `1` or `0`. +- Queue-wrapped runtime sinks report consumed queued items through `queue_advanced_count`. +- Queued file runtime sinks still report generic progress as queue advancement, while `file_backed=true` marks that the queue drains into a file sink. +- This helper does not convert different runtime-shape behaviors into one ambiguous compatibility `Int`. +- `flush()` remains available as the legacy convenience wrapper that sums the fields back into one count. + +### How to Use + +Here are some specific examples provided. + +#### When Need Recommended Generic Flush Progress + +When direct runtime code should inspect flush progress explicitly: +```moonbit +let progress = sink.flush_progress() +``` + +In this example, the caller gets a structured snapshot instead of a mixed `Int`. + +#### When Need Queue-aware Branching During Flush + +When generic runtime support code should react differently for queue-backed and plain-file sinks: +```moonbit +let progress = sink.flush_progress() +if progress.queue_backed { + println(progress.queue_advanced_count) +} +``` + +In this example, queue advancement is explicit and does not need to be inferred from runtime shape. + +### Error Case + +e.g.: +- If the runtime sink shape has no flushable state, the snapshot simply reports zero counts. + +- If callers need file-specific success semantics rather than generic runtime progress, `file_flush()` is the better API. + +### Notes + +1. Prefer `flush_progress()` over `flush()` in new generic runtime code. + +2. Use `flush()` only when older compatibility code still expects one numeric count. diff --git a/docs/api/runtime-sink-flush.md b/docs/api/runtime-sink-flush.md index 88ca3e2..4abb922 100644 --- a/docs/api/runtime-sink-flush.md +++ b/docs/api/runtime-sink-flush.md @@ -2,8 +2,8 @@ name: runtime-sink-flush group: api category: runtime -update-time: 20260613 -description: Flush a RuntimeSink and return how many queued or file-backed operations were advanced. +update-time: 20260707 +description: Compatibility RuntimeSink flush helper that still returns one Int by collapsing generic queue progress and plain-file fallback steps. key-word: - runtime - sink @@ -13,7 +13,7 @@ key-word: ## Runtime-sink-flush -Flush a `RuntimeSink` and return how much work was advanced. This is the direct runtime control API behind configured logger flush behavior. +Flush a `RuntimeSink` and return one compatibility count. This helper is still available for older code, but new generic runtime code should prefer `flush_progress()` because it exposes queue advancement and plain-file fallback steps separately. ### Interface @@ -27,16 +27,18 @@ pub fn RuntimeSink::flush(self : RuntimeSink) -> Int { #### output -- `Int` - Count of advanced operations as reported by the concrete runtime sink variant. +- `Int` - Compatibility count produced from the structured `flush_progress()` result. ### Explanation Detailed rules explaining key parameters and behaviors -- Plain console-style runtime sinks return `0` because they do not keep explicit buffered flush state here. -- Plain file runtime sinks call `FileSink::flush()` and convert the boolean result into `1` or `0`. -- Queue-wrapped runtime sinks forward to the wrapped queue sink's `flush()` behavior. -- This method is the direct sink-level API used by `ConfiguredLogger::flush(...)`. +- This method now delegates to `flush_progress()` and sums `queue_advanced_count + file_flush_step_count` back into one compatibility number. +- Plain console-style runtime sinks still return `0` because the structured result stays zeroed. +- Plain file runtime sinks still expose their generic fallback through `1` or `0`, but that value now comes from `file_flush_step_count` in the structured result. +- Queue-wrapped runtime sinks still return the number of queued records consumed during that flush. +- For queued file sinks, a positive returned count still means queue advancement, not a durable file-write count. +- This method remains the direct sink-level API used by `ConfiguredLogger::flush(...)`. ### How to Use @@ -44,33 +46,39 @@ Here are some specific examples provided. #### When Need Direct Runtime Flush Control -When code is working with a `RuntimeSink` value directly instead of going through `ConfiguredLogger`: +When older code is already built around one numeric flush count: ```moonbit let flushed = sink.flush() ``` -In this example, the runtime sink reports how much flush work was advanced. +In this example, the runtime sink still reports one compatibility count. #### When Need Queue Or File Progress Visibility -When support code should observe whether a direct flush request did useful work: +When code only needs a coarse non-zero check and does not care which runtime dimension advanced: ```moonbit if sink.flush() > 0 { () } ``` -In this example, the return value reflects whether queue draining or file flushing advanced any work. +In this example, the count still reflects generic runtime advancement, not durable file success. ### Error Case e.g.: - If the runtime sink shape has no flushable state, the method may simply return `0`. -- If callers need bounded queue progress, `drain(...)` is the better API. +- If callers need truthful generic progress semantics, `flush_progress()` is the better API. + +- If callers need bounded queue progress, `drain_progress(...)` is usually the better API. + +- If callers need file-specific success semantics on a file-backed sink, `file_flush()` is the better API. ### Notes -1. Use this helper when direct runtime sink flushing matters. +1. Treat this method as a compatibility helper for older numeric code. -2. `ConfiguredLogger::flush(...)` is the higher-level wrapper for config-built loggers. +2. Prefer `flush_progress()` in new generic runtime code. + +3. `ConfiguredLogger::flush(...)` is the higher-level wrapper for config-built loggers. diff --git a/docs/api/runtime-sink-progress.md b/docs/api/runtime-sink-progress.md new file mode 100644 index 0000000..1b0f11a --- /dev/null +++ b/docs/api/runtime-sink-progress.md @@ -0,0 +1,85 @@ +--- +name: runtime-sink-progress +group: api +category: runtime +update-time: 20260707 +description: Public structured generic progress snapshot used by RuntimeSink and ConfiguredLogger flush or drain helpers. +key-word: + - runtime + - progress + - flush + - public +--- + +## Runtime-sink-progress + +`RuntimeSinkProgress` is the public structured progress snapshot returned by the truthful generic `flush_progress(...)` and `drain_progress(...)` helpers. It separates queue advancement from plain file flush fallback steps so callers do not have to infer mixed `Int` semantics from `flush()` or `drain()` alone. + +### Interface + +```moonbit +pub struct RuntimeSinkProgress { + queue_advanced_count : Int + file_flush_step_count : Int + queue_backed : Bool + file_backed : Bool +} +``` + +#### output + +- `RuntimeSinkProgress` - Public generic progress snapshot containing queue advancement count, plain-file flush fallback count, and runtime-shape flags. + +### Explanation + +Detailed rules explaining key parameters and behaviors + +- This is a public root struct, not a type alias. +- `queue_advanced_count` reports how many queued records were consumed by a queue-backed runtime helper call. +- `file_flush_step_count` reports the plain-file fallback step count used by generic helpers on non-queued file sinks, currently `1` for a successful `FileSink::flush()` and `0` otherwise. +- `queue_backed` reports whether the runtime sink shape was queue-backed during the helper call. +- `file_backed` reports whether the runtime sink shape was file-backed during the helper call. +- For queued file sinks, `queue_advanced_count` may be positive while `file_flush_step_count` stays `0`; delayed file failures still belong to `file_flush()` and failure-counter inspection rather than to this generic progress snapshot. + +### How to Use + +Here are some specific examples provided. + +#### When Need Truthful Generic Runtime Progress + +When code should inspect generic flush or drain work without guessing what one `Int` means: +```moonbit +let progress = sink.flush_progress() +if progress.queue_backed { + println(progress.queue_advanced_count) +} +``` + +In this example, queue progress stays explicit instead of being folded into a compatibility count. + +#### When Need To Distinguish Plain File Fallback From Queue Work + +When generic runtime support code should tell plain-file fallback apart from queued advancement: +```moonbit +let progress = logger.drain_progress() +if progress.file_backed && !progress.queue_backed { + println(progress.file_flush_step_count) +} +``` + +In this example, the caller can recognize the plain-file generic fallback path directly. + +### Error Case + +e.g.: +- `RuntimeSinkProgress` itself does not have a runtime failure mode. + +- This type reports generic progress only; it does not prove durable file delivery. + +- If callers need file-specific success semantics, `file_flush()` is still the narrower API. + +### Notes + +1. Prefer this structured result over the legacy `Int` returned by `flush()` and `drain()` when new code can choose. + +2. For queued file sinks, combine this snapshot with `file_flush()`, `file_runtime_state()`, or file failure counters when file outcome matters. diff --git a/docs/api/runtime-sink.md b/docs/api/runtime-sink.md index dc01aeb..41420e8 100644 --- a/docs/api/runtime-sink.md +++ b/docs/api/runtime-sink.md @@ -2,7 +2,7 @@ name: runtime-sink group: api category: runtime -update-time: 20260613 +update-time: 20260707 description: Public runtime sink enum used by config-built synchronous loggers to unify console, file, and queued sink variants. key-word: - runtime @@ -41,8 +41,9 @@ Detailed rules explaining key parameters and behaviors - This is a public enum root type, not a type alias. - The variants cover plain console sinks, plain file sinks, and queue-wrapped forms of those sink families. - `build_logger(...)` and related config-driven construction paths use this type as the concrete sink behind `ConfiguredLogger`. -- The type exposes direct runtime helpers such as `flush()`, `drain()`, `close()`, `pending_count()`, and `dropped_count()`. +- The type exposes direct runtime helpers such as `flush_progress()`, `drain_progress()`, `flush()`, `drain()`, `close()`, `pending_count()`, and `dropped_count()`. - Queue-specific metrics are meaningful only for queued variants, while plain variants usually report `0` for queue counters. +- `flush_progress()` and `drain_progress()` are the recommended truthful generic progress helpers, while `flush()` and `drain()` remain compatibility wrappers that collapse the structured result back into one `Int`. ### How to Use