quill
ManualBackendWorker.h
1 
7 #pragma once
8 
9 #include "quill/backend/BackendOptions.h"
10 #include "quill/backend/BackendWorker.h"
11 #include <cassert>
12 #include <chrono>
13 #include <limits>
14 
15 QUILL_BEGIN_NAMESPACE
16 
21 {
22 public:
23  explicit ManualBackendWorker(detail::BackendWorker* backend_worker)
24  : _backend_worker(backend_worker)
25  {
26  }
27 
28  ~ManualBackendWorker() { _backend_worker->_exit(); }
29 
38  void init(BackendOptions options)
39  {
40  options.sleep_duration = std::chrono::nanoseconds{0};
41  options.enable_yield_when_idle = false;
42  _backend_worker->_init(options);
43  }
44 
53  void poll_one()
54  {
55  assert((_backend_worker->_options.sleep_duration.count() == 0) &&
56  "call init() prior to calling this function");
57  assert((_backend_worker->_options.enable_yield_when_idle == false) &&
58  "call init() prior to calling this function");
59  assert((_backend_worker->_worker_thread_id.load() != 0) &&
60  "call init() prior to calling this function");
61  assert((_backend_worker->_worker_thread_id.load() == detail::get_thread_id()) &&
62  "poll() must be always called from the same thread");
63 
64  QUILL_TRY { _backend_worker->_poll(); }
65 #if !defined(QUILL_NO_EXCEPTIONS)
66  QUILL_CATCH(std::exception const& e) { _backend_worker->_options.error_notifier(e.what()); }
67  QUILL_CATCH_ALL()
68  {
69  _backend_worker->_options.error_notifier(std::string{"Caught unhandled exception."});
70  } // clang-format on
71 #endif
72  }
73 
79  void poll()
80  {
81  while (!_backend_worker->_check_frontend_queues_and_cached_transit_events_empty())
82  {
83  poll_one();
84  }
85  }
86 
91  void poll(std::chrono::microseconds timeout)
92  {
93  auto const start = std::chrono::steady_clock::now();
94  while (!_backend_worker->_check_frontend_queues_and_cached_transit_events_empty())
95  {
96  poll_one();
97 
98  auto const now = std::chrono::steady_clock::now();
99 
100  if ((now - start) > timeout)
101  {
102  break;
103  }
104  }
105  }
106 
107 private:
108  detail::BackendWorker* _backend_worker;
109 };
110 
111 QUILL_END_NAMESPACE
bool enable_yield_when_idle
The backend employs "busy-waiting" by spinning around each frontend thread&#39;s queue.
Definition: BackendOptions.h:44
void poll(std::chrono::microseconds timeout)
This function behaves like poll() but will stop polling if the specified timeout duration is reached ...
Definition: ManualBackendWorker.h:91
std::function< void(std::string const &)> error_notifier
The backend may encounter exceptions that cannot be caught within user threads.
Definition: BackendOptions.h:162
void init(BackendOptions options)
Initializes the ManualBackendWorker with the specified backend options.
Definition: ManualBackendWorker.h:38
std::chrono::nanoseconds sleep_duration
Specifies the duration the backend sleeps if there is no remaining work to process in the queues...
Definition: BackendOptions.h:49
This class can be used when you want to run the backend worker on your own thread.
Definition: ManualBackendWorker.h:20
void poll()
Continuously polls the backend worker until all queues are empty.
Definition: ManualBackendWorker.h:79
void poll_one()
Polls all thread-local SPSC queues and caches the log statements, processing and writing the log stat...
Definition: ManualBackendWorker.h:53
Definition: BackendWorker.h:72
QUILL_NODISCARD QUILL_EXPORT QUILL_ATTRIBUTE_USED uint32_t get_thread_id() noexcept
Returns the os assigned ID of the thread.
Definition: ThreadUtilities.h:193
Configuration options for the backend.
Definition: BackendOptions.h:30