qb
2.0.0.0
C++17 Actor Framework
|
Base class for all actors in the qb framework. More...
#include <Actor.h>
Classes | |
class | EventBuilder |
Helper class for building and sending events to actors. More... |
Public Member Functions | |
Built-in Event Handlers | |
void | on (KillEvent const &event) noexcept |
Handler for KillEvent. | |
void | on (SignalEvent const &event) noexcept |
Handler for SignalEvent. | |
void | on (UnregisterCallbackEvent const &event) noexcept |
Handler for UnregisterCallbackEvent. | |
void | on (PingEvent const &event) noexcept |
Handler for PingEvent. |
Public Member Functions | |
This part describes how to manage Actor loop callback, events registration, several ways to send events and create referenced actors. | |
template<typename _Actor> | |
void | registerCallback (_Actor &actor) const noexcept |
Register a looped callback for this actor. | |
template<typename _Actor> | |
void | unregisterCallback (_Actor &actor) const noexcept |
Unregister a previously registered looped callback for this actor. | |
template<typename _Event, typename _Actor> | |
void | registerEvent (_Actor &actor) const noexcept |
Subscribe this actor to listen for a specific event type. | |
template<typename _Event, typename _Actor> | |
void | unregisterEvent (_Actor &actor) const noexcept |
Unsubscribe this actor from listening to a specific event type. | |
EventBuilder | to (ActorId dest) const noexcept |
Get an EventBuilder for sending chained events to a destination actor. | |
template<typename _Event, typename... _Args> | |
_Event & | push (ActorId const &dest, _Args &&...args) const noexcept |
Send a new event in an ordered fashion to a destination actor, returning a reference to it. | |
template<typename _Event, typename... _Args> | |
void | send (ActorId const &dest, _Args &&...args) const noexcept |
Send a new event in an unordered fashion to a destination actor. | |
template<typename _Event, typename... _Args> | |
_Event | build_event (qb::ActorId const source, _Args &&...args) const noexcept |
Construct an event locally, intended for immediate self-processing or direct calls. | |
template<typename _Type> | |
bool | is (uint32_t const id) const noexcept |
Check if a given ID matches the type ID of _Type. | |
template<typename _Type> | |
bool | is (RequireEvent const &event) const noexcept |
Check if a RequireEvent is for a specific actor type. | |
template<typename... _Actors> | |
bool | require () const noexcept |
Request discovery of other actors of specified types. | |
template<typename _Event, typename... _Args> | |
void | broadcast (_Args &&...args) const noexcept |
Broadcast an event to all actors on all cores. | |
void | reply (Event &event) const noexcept |
Reply to the source of a received event, reusing the event object. | |
void | forward (ActorId dest, Event &event) const noexcept |
Forward a received event to a new destination, reusing the event object. | |
Pipe | getPipe (ActorId dest) const noexcept |
Get direct access to the underlying communication pipe for a destination actor. | |
template<typename _Actor, typename... _Args> | |
_Actor * | addRefActor (_Args &&...args) const |
Create and initialize a new referenced actor on the same VirtualCore. |
Public Accessors | |
ActorId | id () const noexcept |
Get ActorId. | |
CoreId | getIndex () const noexcept |
Get core index. | |
std::string_view | getName () const noexcept |
Get derived class name. | |
const CoreIdSet & | getCoreSet () const noexcept |
Get the set of cores that this actor's VirtualCore can communicate with. | |
uint64_t | time () const noexcept |
Get current time from the VirtualCore's perspective (nanoseconds since epoch). | |
template<typename _ServiceActor> | |
_ServiceActor * | getService () const noexcept |
Get direct access to ServiceActor* in same core. | |
bool | is_alive () const noexcept |
Check if Actor is alive and processing events. |
Construction/Destruction | |
Actor () noexcept | |
Default constructor. | |
virtual | ~Actor () noexcept=default |
Virtual destructor. | |
virtual bool | onInit () |
Initialization callback, called once after construction and ID assignment. | |
void | kill () const noexcept |
Terminate this actor and mark it for removal from the system. |
Base class for all actors in the qb framework.
The Actor class is the fundamental unit of computation in the qb framework. Actors communicate exclusively by passing messages (events) to each other, which are processed by event handlers. This messaging pattern ensures isolation and prevents shared mutable state, making the system more robust for concurrent and distributed applications.
Each actor:
Example usage:
|
protectednoexcept |
Default constructor.
Creates an actor with a default (invalid) ID. The actual ID will be assigned when the actor is registered with a VirtualCore.
|
protectedvirtualdefaultnoexcept |
Virtual destructor.
Ensures proper cleanup of derived actor classes.
|
inlineprotectedvirtual |
Initialization callback, called once after construction and ID assignment.
This method is called when the actor is added to the system, before it starts processing any events. Override this method to perform initialization tasks such as registering event handlers and setting up actor state.
Crucial for registerEvent<EventType>(*this) calls. Example:
|
noexcept |
Terminate this actor and mark it for removal from the system.
Marks the actor for removal from the system. After calling this method, the actor will no longer receive new events (though it may process events already in its queue) and will be cleaned up by the framework during the next appropriate cycle.
This method is typically called from within an event handler (e.g., on(qb::KillEvent&)) when the actor decides to terminate itself, or it can be triggered by sending a KillEvent to the actor.
|
noexcept |
Handler for KillEvent.
Default handler for the KillEvent which terminates the actor by calling this->kill(). Derived classes can override this handler to perform cleanup actions before termination, but should typically call Actor::kill() or this->kill() at the end of their implementation to ensure proper termination.
event | The received kill event (often unused in overrides, but available). Example of overriding: // Perform cleanup: close connections, release resources not handled by RAII, etc.
closeConnections();
releaseResources();
// Finally, ensure the actor is marked for termination
Actor::kill(); // Or just kill();
}
|
|
noexcept |
Handler for SignalEvent.
Default handler for system signals (e.g., SIGINT) that terminates the actor. Derived classes can override this handler to perform custom signal handling. If overridden, ensure proper state management or actor termination if needed.
event | The received signal event, containing event.signum. Example of overriding: if (event.signum == SIGINT) {
// Custom shutdown logic here...
kill(); // Terminate the actor
reloadConfig();
} else {
// Default behavior for other signals might be to kill, or call base:
// Actor::on(event);
}
}
#define LOG_WARN(X) Warning-level log macro (no-op if QB_STDOUT_LOG is not defined) Definition io.h:236 |
|
noexcept |
Handler for UnregisterCallbackEvent.
This handler unregisters a previously registered callback for this actor. It should generally not be overridden by derived classes as its behavior is fixed.
event | The received unregister callback event. |
|
noexcept |
Handler for PingEvent.
Responds to ping requests, primarily used for actor alive checks, diagnostics, and by the require<T>() mechanism for actor discovery. The default implementation sends a RequireEvent back to the source of the PingEvent if the ping type matches.
event | The received ping event, containing event.type to match against. |
|
inlinenodiscardnoexcept |
|
nodiscardnoexcept |
Get core index.
|
nodiscardnoexcept |
Get derived class name.
|
nodiscardnoexcept |
Get the set of cores that this actor's VirtualCore can communicate with.
This reflects the CoreSet the VirtualCore was initialized with.
|
nodiscardnoexcept |
Get current time from the VirtualCore's perspective (nanoseconds since epoch).
This value is optimized and cached/updated by the VirtualCore at the beginning of each of its processing loops. Thus, multiple calls to time() within the same event handler or onCallback() invocation will return the same timestamp.
For a continuously updating, high-precision timestamp, use qb::NanoTimestamp()::count() from <qb/system/timestamp.h>.
|
nodiscardnoexcept |
Get direct access to ServiceActor* in same core.
|
nodiscardnoexcept |
Check if Actor is alive and processing events.
An actor is considered alive until its kill() method has been called AND the VirtualCore has processed its removal. It might still process events in its queue after kill() is called but before it's fully removed.
|
noexcept |
Register a looped callback for this actor.
_Actor | The derived actor type, which must inherit from qb::ICallback. |
actor | A reference to the derived actor instance (usually *this). |
The registered onCallback() method (from qb::ICallback) will be called by the VirtualCore during each of its processing loop iterations, after event processing. This allows the actor to perform periodic tasks or background operations. The callback remains active until explicitly unregistered or the actor is terminated.
|
noexcept |
Unregister a previously registered looped callback for this actor.
_Actor | The derived actor type. |
actor | A reference to the derived actor instance (usually *this). |
Stops the periodic invocation of the actor's onCallback() method. It is safe to call this even if no callback is currently registered.
|
noexcept |
Subscribe this actor to listen for a specific event type.
_Event | The type of event to listen for (must derive from qb::Event). |
_Actor | The derived actor type that implements the on(_Event&) handler. |
actor | A reference to the derived actor instance (usually *this). |
After registration, if an event of type _Event is sent to this actor's ID, its corresponding void on(_Event& event) or void on(const _Event& event) method will be invoked by the VirtualCore. This is typically called within the actor's onInit() method.
|
noexcept |
Unsubscribe this actor from listening to a specific event type.
_Event | The type of event to stop listening for. |
_Actor | The derived actor type. |
actor | A reference to the derived actor instance (usually *this). |
After this call, the actor will no longer receive new events of type _Event. It is safe to call this for event types the actor was not subscribed to.
|
nodiscardnoexcept |
Get an EventBuilder for sending chained events to a destination actor.
dest | The ActorId of the destination actor. |
This provides a fluent interface for sending multiple events to the same actor:
All events pushed via the builder are sent in an ordered fashion, similar to push().
|
noexcept |
Send a new event in an ordered fashion to a destination actor, returning a reference to it.
_Event | The type of event to create and send (must derive from qb::Event). |
_Args | Types of arguments to forward to the _Event constructor. |
dest | The ActorId of the destination actor. |
args | Arguments to forward to the constructor of _Event. |
This is the primary and recommended method for sending events. Events sent using push() to the same destination actor from the same source actor are guaranteed to be received in the order they were pushed. The event is queued and sent by the VirtualCore at an appropriate time (usually at the end of the current processing loop). Supports events with non-trivially destructible members (e.g., std::string, std::vector).
|
noexcept |
Send a new event in an unordered fashion to a destination actor.
_Event | The type of event to create and send (must derive from qb::Event and be trivially destructible). |
_Args | Types of arguments to forward to the _Event constructor. |
dest | The ActorId of the destination actor. |
args | Arguments to forward to the constructor of _Event. |
Events sent using send() are not guaranteed to be received in the order they were sent, even if sent to the same destination from the same source. This method may offer slightly lower latency for same-core communication in specific scenarios but sacrifices ordering.
|
nodiscardnoexcept |
Construct an event locally, intended for immediate self-processing or direct calls.
_Event | The type of event to build (must derive from qb::Event). |
_Args | Types of arguments to forward to the _Event constructor. |
source | The ActorId to be set as the source of this event (usually this->id()). |
args | Arguments to forward to the constructor of _Event. |
This method creates an event object but does not send it through the actor system's messaging queues. It's typically used to prepare an event that will be passed directly to one of the actor's own on() handlers or to a referenced actor's methods. The dest field of the event will be set to this->id().
|
inlinenodiscardnoexcept |
Check if a given ID matches the type ID of _Type.
_Type | The type to check against. |
id | The type ID (usually from an event or actor) to compare. |
|
inlinenodiscardnoexcept |
Check if a RequireEvent is for a specific actor type.
_Type | The actor type to check against. |
event | The RequireEvent to inspect. |
|
noexcept |
Request discovery of other actors of specified types.
_Actors | Variadic template pack of actor types to discover. |
For each type in _Actors, this method broadcasts a PingEvent. Live actors of the specified types will respond with a RequireEvent, which this actor must be registered to handle (via registerEvent<RequireEvent>(*this)). The on(RequireEvent&) handler can then use is<_ActorType>(event) to identify responses.
|
noexcept |
Broadcast an event to all actors on all cores.
_Event | The type of event to broadcast (must derive from qb::Event). |
_Args | Types of arguments to forward to the _Event constructor. |
args | Arguments to forward to the constructor of _Event. |
The event will be sent to every actor currently running in the system across all VirtualCores. The source of the event will be this actor's ID. Use push<MyEvent>(qb::BroadcastId(core_id), ...) to broadcast only to a specific core.
|
noexcept |
Reply to the source of a received event, reusing the event object.
event | The event object that was received. This event will be modified (its dest and source will be swapped) and sent back to its original source. |
This is the most efficient way to send a response back to the sender of an event. The original event object is reused, minimizing allocations and copies. The on() handler receiving the event must take it by non-const reference (MyEvent& event) to allow reply() to modify and effectively consume it.
Forward a received event to a new destination, reusing the event object.
dest | The ActorId of the new destination actor. |
event | The event object that was received. This event will be modified (its dest will be updated to dest) and sent. The original source of the event is preserved. |
This is an efficient way to delegate an event to another actor without creating a new event. The on() handler receiving the event must take it by non-const reference (MyEvent& event) to allow forward() to modify and effectively consume it.
Get direct access to the underlying communication pipe for a destination actor.
dest | The ActorId of the destination actor. |
This provides lower-level access to the event sending mechanism. It can be useful for performance-critical scenarios, especially when sending multiple events to the same destination or when needing to pre-allocate buffer space for large events using Pipe::allocated_push().
_Actor * qb::Actor::addRefActor | ( | _Args &&... | args | ) | const |
Create and initialize a new referenced actor on the same VirtualCore.
_Actor | The concrete derived actor type to create (must inherit from qb::Actor). |
_Args | Types of arguments to forward to the _Actor's constructor. |
args | Arguments to forward to the constructor of _Actor. |
Referenced actors are created on the same VirtualCore as the calling (parent) actor. The parent receives a raw pointer to the child actor. This allows for direct method calls from the parent to the child, bypassing the event queue for the child. The child actor still has its own ActorId and can receive events normally.