Corium 1.1.0
High-Performance Zero-Heap C++20 MPSC Application Runtime
Loading...
Searching...
No Matches
BackgroundService.hpp
Go to the documentation of this file.
1
7#pragma once
8
9#include "corium/Service.hpp"
11
12#include <chrono>
13#include <exception>
14#include <stop_token>
15#include <thread>
16
17namespace corium {
18
28template <
29 typename EventVariantType = DefaultEvents,
30 typename QueuePolicy = BoundedMpscQueuePolicy<EventVariantType, 1024>,
31 typename SignalPolicy = CallbackSignalPolicy,
32 typename StoragePolicy = DefaultStoragePolicy,
33 typename OverflowPolicy = DropNewestOverflowPolicy
34>
35class BackgroundService : public Service<EventVariantType, QueuePolicy, SignalPolicy, StoragePolicy, OverflowPolicy> {
36public:
39
40 BackgroundService() = default;
41
45
47 {
48 stop();
49 join();
50 }
51
54
55 BackgroundService(BackgroundService&&) noexcept = default;
56 BackgroundService& operator=(BackgroundService&&) noexcept = default;
57
65 template <typename Rep, typename Period>
66 std::size_t waitAndPump(const std::stop_token& stopToken, const std::chrono::duration<Rep, Period>& timeout)
67 {
68 if (this->incomingBus().empty() && !stopToken.stop_requested()) {
69 this->incomingBus().signalPolicy().wait_for(timeout);
70 }
71
72 std::size_t processed = 0;
73 while (!stopToken.stop_requested()) {
74 if (!this->incomingBus().processOne()) {
75 break;
76 }
77 processed++;
78 }
79 return processed;
80 }
81
83 template <typename Derived>
84 void startThread(Derived* derived)
85 {
86 _thread = std::jthread([this, derived](std::stop_token stopToken) {
87#if __cpp_exceptions
88 using EvVariant = EventVariantType;
89 try {
90 derived->run(stopToken);
91 } catch (const std::exception& e) {
92 if constexpr (requires { derived->onError(std::current_exception()); }) {
93 derived->onError(std::current_exception());
94 } else if constexpr (requires { derived->onError(e.what()); }) {
95 derived->onError(e.what());
96 }
97 if constexpr (has_variant_type_v<ErrorEvent, EvVariant>) {
98 this->postHighPriority(ErrorEvent{1, reinterpret_cast<uintptr_t>(e.what())});
99 }
100 } catch (...) {
101 if constexpr (requires { derived->onError(std::current_exception()); }) {
102 derived->onError(std::current_exception());
103 }
104 if constexpr (has_variant_type_v<ErrorEvent, EvVariant>) {
105 this->postHighPriority(ErrorEvent{1, 0});
106 }
107 }
108#else
109 derived->run(stopToken);
110#endif
111 });
112 }
113
115 void stop() noexcept
116 {
117 if (_thread.joinable()) {
118 _thread.request_stop();
119 }
120 }
121
123 void join() noexcept
124 {
125 if (_thread.joinable()) {
126 _thread.join();
127 }
128 }
129
130private:
131 std::jthread _thread;
132};
133
136template <typename EventVariant = DefaultEvents>
138 EventVariant,
142>;
143
147template <typename EventVariant = DefaultEvents, std::size_t Capacity = 64>
149 EventVariant,
153>;
154
155} // namespace corium
Lightweight thread-safe background service interface.
Compile-time type index resolution for std::variant alternative types.
Multi-threaded background worker service owning a dedicated std::jthread. Integrates incoming event q...
Definition BackgroundService.hpp:35
BackgroundService & operator=(const BackgroundService &)=delete
BackgroundService(const BackgroundService &)=delete
void stop() noexcept
Request cancellation on worker std::jthread.
Definition BackgroundService.hpp:115
void startThread(Derived *derived)
Start execution loop on dedicated std::jthread.
Definition BackgroundService.hpp:84
~BackgroundService()
Definition BackgroundService.hpp:46
BackgroundService(BackgroundService &&) noexcept=default
typename Base::EventVariant EventVariant
Definition BackgroundService.hpp:38
void join() noexcept
Join background std::jthread cleanly.
Definition BackgroundService.hpp:123
std::size_t waitAndPump(const std::stop_token &stopToken, const std::chrono::duration< Rep, Period > &timeout)
Wait for incoming events or timeout, then pump all available incoming events. Safe for use inside wor...
Definition BackgroundService.hpp:66
BackgroundService(ServiceContextT< EventVariant > context)
Definition BackgroundService.hpp:42
SignalPolicy & signalPolicy() noexcept
Access reference to signal policy.
Definition EventBus.hpp:175
Queue Policy for fixed-capacity, zero-allocation lock-free MPSC RingBuffer.
Definition QueuePolicies.hpp:43
Signal Policy invoking an edge-triggered callback on 0->1 transition when queue becomes non-empty.
Definition SignalPolicies.hpp:91
Zero-overhead Queue Policy for services or buses that do not receive or queue incoming events....
Definition QueuePolicies.hpp:240
Signal Policy for busy-spin / polling event loops (sub-microsecond latency, zero signaling cost).
Definition SignalPolicies.hpp:72
Non-allocating base class for synchronous or thread-agnostic services. Provides event producing (post...
Definition Service.hpp:37
EventVariantType EventVariant
Definition Service.hpp:39
IncomingBus & incomingBus() noexcept
Definition Service.hpp:142
bool processOne()
Process a single incoming event from the service queue.
Definition Service.hpp:89
ServiceContextT< EventVariant > & context() noexcept
Definition Service.hpp:118
void postHighPriority(EventType &&event) const
Post a high-priority event into the main application event queue.
Definition Service.hpp:130
Definition Application.hpp:16
std::variant< QuitEvent, TickEvent, UpdateEvent, ErrorEvent, SignalEvent > DefaultEvents
Default variant list of core Corium events.
Definition Events.hpp:62
FixedStoragePolicy< 8, 32 > DefaultStoragePolicy
Default storage policy (8 handlers per event type, 32 bytes inline delegate storage).
Definition StoragePolicies.hpp:24
System, hardware, or framework error event.
Definition Events.hpp:37
Policy configuring compile-time handler capacity and delegate inline storage size.
Definition StoragePolicies.hpp:18