Manual Backend Worker¶
ManualBackendWorker is an advanced integration path for applications that need to run Quill’s backend worker on a user-managed thread instead of using Backend::start().
In most applications you should still prefer the normal backend thread created by Backend::start(). Use ManualBackendWorker only when you need explicit control over the backend thread’s lifecycle or polling loop.
ManualBackendWorker can also be used to run Quill without spawning any additional thread. Applications that already have an event loop or a policy against extra threads can drive the backend by calling poll_one() from their own thread at a cadence they choose. init() forces sleep_duration = 0 and enable_yield_when_idle = false, so poll_one() never sleeps or yields the calling thread — it only does work when there is work to do and returns immediately otherwise.
Note that the frontend hot path is designed for a producer and consumer on different threads. Running both on the same thread still works, but you pay for synchronization and cache-line padding you do not need. Prefer Backend::start() if it fits your threading model.
Basic Usage¶
Start a dedicated thread that will own the manual backend worker.
Call
Backend::acquire_manual_backend_worker()exactly once for the process.Call
init()on that same thread.Periodically call
poll()orpoll(timeout)on that same thread.Before the thread exits, call
poll()one last time to drain pending log messages, then callshutdown()on that same thread.
Example¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | |
Important Rules¶
Use exactly one thread to own and drive the
ManualBackendWorker.The thread that calls
init()must also callshutdown()before it exits.Do not rely on the destructor for shutdown ordering.
The manual backend thread may log, but it must not use paths that wait for the backend to flush its own queue. In particular, avoid
logger->flush_log()andFrontend::remove_logger_blocking()on that same thread. If a logger has immediate flush enabled, the implicit flush is skipped for log calls from the manual backend thread.Backend::acquire_manual_backend_worker()is mutually exclusive withBackend::start(). You can only choose one model per process.The built-in signal handler setup is not performed for
ManualBackendWorker.
When To Use It¶
Good fits:
integrating Quill into an existing event loop
running backend polling from a thread already managed by a larger framework
applications that need strict ownership of backend thread startup and shutdown
applications with a no-extra-threads policy, where Quill must run without spawning its own backend thread
Avoid it when:
Backend::start()already fits your threading modelyou only want a simpler setup path
Driving The Backend From Your Own Thread¶
Call poll_one() at a natural quiet point of the event loop, often enough to keep frontend queues from filling up.
poll_one() performs formatting and sink I/O on the calling thread. For latency-sensitive threads, a custom sink that forwards records to another process or thread (for example via a shared-memory ring) can keep the polling thread free of heavy I/O. See Sinks.
See also ManualBackendWorker and Backend::acquire_manual_backend_worker().