4.2 KiB
name, group, category, update-time, description, key-word
| name | group | category | update-time | description | key-word | ||||
|---|---|---|---|---|---|---|---|---|---|
| async-logger-run | api | async | 20260707 | Start the async logger worker loop so queued records are drained to the underlying sink while lifecycle and failure state are reset and updated around execution. |
|
Async-logger-run
Start the async logger worker loop. This is the core runtime API that drains queued records to the underlying sink and updates worker lifecycle state around that drain loop.
Interface
pub async fn[S : @bitlogger.Sink] AsyncLogger::run(self : AsyncLogger[S]) -> Unit {}
input
self : AsyncLogger[S]- Async logger whose queue should be drained by the worker loop.
output
Unit- No return value. The method runs until the queue is closed or a worker failure occurs.
Explanation
Detailed rules explaining key parameters and behaviors
run()setsis_runningtotruebefore worker execution begins.run()moves the logger lifecycle phase fromreadyorfailedintorunning.run()now enforces a single-worker contract. If the same logger already has a running worker, the later call raisesAsyncLoggerAlreadyRunninginstead of silently starting another drain loop.- If the logger is already closed,
run()raisesAsyncLoggerClosedinstead of trying to restart a terminal logger. - Every invocation clears previous failure state first by setting
has_failed=falseandlast_error()to an empty string once thatrun()call has actually started executing. - The method then keeps draining records until
queue.get()stops withAsyncLoggerClosedor a worker error escapes. - On a normal queue-close exit,
run()leaves the logger inclosedif shutdown/close had already started, otherwise it returns toready. - On failure, the logger records
last_error, transitions tofailedorclosed_failed, and then raises the error back out ofrun(). - A worker failure does not guarantee the async backlog was fully drained first. If the failure happens after some records were already written, later queued records can remain pending when
run()exits. - A later
run()invocation can resume draining that retained backlog, but the stale failure flag and stalelast_error()value are only cleared after the new worker call actually begins running.
How to Use
Here are some specific examples provided.
When Need Background Queue Drain
When async logging should be processed by a worker task:
let logger = async_logger(console_sink())
@async.with_task_group(group => {
group.spawn_bg(() => logger.run())
logger.info("started")
logger.shutdown()
})
In this example, run() is the worker loop that makes the async logger actually deliver queued records.
When Need Explicit Worker Lifetime Control
When worker execution should be started under application control:
group.spawn_bg(() => logger.run())
In this example, the application decides when the worker begins instead of hiding that lifecycle step.
Error Case
e.g.:
-
If the worker loop fails,
has_failed()becomestrue,last_error()stores the error text, andrun()raises that failure to the caller. -
After a failed run,
pending_count()can still be greater than zero until later shutdown or restart logic finishes handling the retained backlog. -
If
run()is never started, accepted records may remain queued and not reach the sink. -
A later
run()attempt starts from a fresh failure flag and emptylast_error()string once that retrying worker has actually started, even if an earlier run failed. -
Starting more than one
run()task for the same logger raisesAsyncLoggerAlreadyRunningon the later attempt. -
Starting
run()after a terminal close path raisesAsyncLoggerClosed.
Notes
-
async_logger(...)only constructs the logger;run()is what activates queue draining. -
Pair this API with
shutdown()for a complete worker lifecycle. -
Pair it with
has_failed(),last_error(), orstate()when tests need to inspect how a worker exit affected logger health. -
Start one deliberate worker task per logger. A concurrent second startup now fails explicitly with
AsyncLoggerAlreadyRunning.