Sen API
Sen Libraries
Loading...
Searching...
No Matches
sen::kernel::RunApi Class Reference

What can be done while a component is running. More...

#include <component_api.h>

Inheritance diagram for sen::kernel::RunApi:

Public Types

using TerminalOwnership = ::sen::kernel::TerminalOwnership
 The logger state below is per process, not per kernel. The relay sink and the record of what the console sinks were are statics in libkernel, so they outlive any Kernel and are shared by every kernel in the process. "Every logger" means every logger in libkernel's registry, which no kernel owns. configureSpdlog replaces the sink vector of every logger that already exists, so KernelImpl::configure re-attaches the relay straight afterwards, and a second kernel configured in the same process keeps working. A logger made by any route other than getOrCreateLogger, a direct spdlog factory for instance, is not reached at all.

Public Member Functions

 RunApi (Kernel &kernel, impl::KernelImpl &kernelImpl, impl::Runner *runner, std::atomic_bool &stopRequested, const VarMap &config, Guarded< TimeStamp > &timePoint) noexcept
 ~RunApi () noexcept=default
const std::atomic_bool & stopRequested () const noexcept
 True if stop has been requested by the runtime.
void drainInputs ()
 Perform any request coming from the outside and drainInputs all the local data structures with their most up-to-date value. This method is thread-safe.
void update ()
 This calls update() on all the objects registered by the component.
void commit ()
 Send changes, so that they become visible to other participants. This includes object additions and removals, property changes and emitted events that others might have interest in. This method is thread-safe.
FuncResult execLoop (Duration cycleTime, std::function< void()> &&func=nullptr, bool logOverruns=true)
 A basic execution loop. Func is an optional callback that will be invoked on each cycle. logOverruns keeps the log lines for a missed deadline: an execution time overrun and the two ways a cycle is lost. The Tracy messages are emitted either way.
TimeStamp getStartTime () const noexcept
 The initial simulation time for the objects in the component.
TimeStamp getTime () const noexcept
 The (potentially virtualized) time.
std::optional< Duration > getTargetCycleTime () const noexcept
 If present, it returns the configured cycle time for iterations.
ComponentMonitoringInfo fetchComponentMonitoringInfo () const
 Monitoring information of the calling component.
KernelMonitoringInfo fetchMonitoringInfo () const
 Monitoring information of all components loaded by the kernel.
Span< const ComponentInfo > getImportedPackages () const noexcept
 Build information for all imported packages (from pipeline components). The returned span references kernel-owned storage that is stable for the lifetime of the kernel.
Span< const ComponentInfo > getLoadedComponents () const noexcept
 Build information for every component loaded into the kernel, excluding pipeline components (which are built from imports and have no individual build identity) and the internal kernel component. The returned span references kernel-owned storage that is stable for the lifetime of the kernel.
std::optional< uint32_t > getTransportProtocolVersion () const noexcept
 Version of the currently installed transport protocol. Empty when no transport is installed. Static for the lifetime of the kernel.
Tracer & getTracer () const noexcept
 Create a scoped zone used for tracing runtime performance.
const VarMap & getConfig () const noexcept
 Gets the configuration associated with this component.
CustomTypeRegistry & getTypes () noexcept
 The types registered into the kernel.
void requestKernelStop (int exitCode=0)
 Issues an asynchronous request to stop the kernel. The request is ignored if a previous stop request was issued.
std::shared_ptr< ObjectSource > getSource (const BusAddress &address)
 Gets an object source, where objects can be found and published.
std::shared_ptr< ObjectSource > getSource (const std::string &address)
 Gets an object source, where objects can be found and published. The address parameter must be given as <session-name>.<bus-name>.
SessionsDiscoverer & getSessionsDiscoverer () noexcept
 Object that allows discovering sessions and buses.
const ProcessInfo * fetchOwnerInfo (const Object *object) const noexcept
 Gets information about the process where an object is. Returns nullptr if the object resides in the current process.
const std::string & getAppName () const noexcept
 Gets the (optional) application name passed to the kernel as a configuration parameter.
std::vector< BusAddress > getConfiguredBusAddresses () const
 Gets configured non-local bus addresses.
::sen::impl::WorkQueue * getWorkQueue () const noexcept
 The work queue of this runner.
template<typename T, typename Bus>
std::shared_ptr< Subscription< T > > selectAllFrom (const Bus &bus)
 Subscribe to every object of type T on bus. The returned Subscription owns the kernel-side wiring; destruct it to stop.
template<typename T, typename Bus>
std::shared_ptr< Subscription< T > > selectAllFrom (const Bus &bus, typename sen::ObjectList< T >::Callback onAdded, typename sen::ObjectList< T >::Callback onRemoved=nullptr)
 As above, plus addition/removal callbacks installed before subscribing so they fire for objects already present. Pass nullptr to skip either.
template<typename T, typename Bus>
std::shared_ptr< Subscription< T > > selectFrom (const Bus &bus, const std::string &query, typename sen::ObjectList< T >::Callback onAdded=nullptr, typename sen::ObjectList< T >::Callback onRemoved=nullptr)
 Subscription against an arbitrary Sen query (with WHERE conditions). Example: selectFrom<Shape>(bus, R"(SELECT Shape FROM local.bus WHERE color IN ("red"))"). Installs the callbacks before subscribing. Pass nullptr to skip either.
std::filesystem::path getConfigFilePath () const noexcept
 Gets the path to the configuration file used to construct the kernel. It might be empty if the kernel is programmatically configured.

Static Public Member Functions

static std::shared_ptr< spdlog::logger > getOrCreateLogger (const std::string &loggerName)
 Registers a new logger in the kernel if it does not exist, or returns the existing one by name. Used to propagate the logger configuration to other packages/components that use it.
static void applyToAllLoggers (std::function< void(std::shared_ptr< spdlog::logger >)> &&func)
 Applies the input function to all loggers kept in the logger registry. Used by the logmaster component.
static Result< LoggerSinkRegistration, ExecError > addLoggerSink (std::shared_ptr< spdlog::sinks::sink > sink, TerminalOwnership terminal=TerminalOwnership::shared)
 Sends every logger's output to sink, including loggers made afterwards.
static FuncResult removeLoggerSink (const std::shared_ptr< spdlog::sinks::sink > &sink)
 Stops sending output to sink. Restores the console sinks if this was the last registered sink claiming the terminal. For a component being unloaded.
static FuncResult setAllLoggersLevel (spdlog::level::level_enum level)
 Sets the level on every logger the kernel knows and on every logger made afterwards.
static void setCrashBannerDescriptor (int descriptor) noexcept
 Where the kernel writes the crash banner, the few lines naming what died and where the report went, for a component that has taken stderr over.
static void prepareCurrentThreadForCrashReports () noexcept
 Give the calling thread the alternate signal stack the crash handler needs.
static spdlog::level::level_enum getAllLoggersLevel ()
 The level setAllLoggersLevel last set, which is also the level a new logger starts from.

Friends

void impl::remoteProcessDetected (RunApi &api, const ProcessInfo &processInfo)
void impl::remoteProcessLost (RunApi &api, const ProcessInfo &processInfo)

Detailed Description

What can be done while a component is running.

Member Typedef Documentation

◆ TerminalOwnership

The logger state below is per process, not per kernel. The relay sink and the record of what the console sinks were are statics in libkernel, so they outlive any Kernel and are shared by every kernel in the process. "Every logger" means every logger in libkernel's registry, which no kernel owns. configureSpdlog replaces the sink vector of every logger that already exists, so KernelImpl::configure re-attaches the relay straight afterwards, and a second kernel configured in the same process keeps working. A logger made by any route other than getOrCreateLogger, a direct spdlog factory for instance, is not reached at all.

spdlog appears in these signatures deliberately. It makes a component's ABI depend on being built against the same spdlog as the kernel, which is acceptable because Sen builds the kernel and its components from one source tree, and a component that renders logs wants spdlog's own formatting. Revisit it first if components ever ship separately from the kernel.

Constructor & Destructor Documentation

◆ RunApi()

sen::kernel::RunApi::RunApi ( Kernel & kernel,
impl::KernelImpl & kernelImpl,
impl::Runner * runner,
std::atomic_bool & stopRequested,
const VarMap & config,
Guarded< TimeStamp > & timePoint )
noexcept

◆ ~RunApi()

sen::kernel::RunApi::~RunApi ( )
defaultnoexcept

Member Function Documentation

◆ stopRequested()

const std::atomic_bool & sen::kernel::RunApi::stopRequested ( ) const
nodiscardnoexcept

True if stop has been requested by the runtime.

◆ drainInputs()

void sen::kernel::RunApi::drainInputs ( )

Perform any request coming from the outside and drainInputs all the local data structures with their most up-to-date value. This method is thread-safe.

◆ update()

void sen::kernel::RunApi::update ( )

This calls update() on all the objects registered by the component.

◆ commit()

void sen::kernel::RunApi::commit ( )

Send changes, so that they become visible to other participants. This includes object additions and removals, property changes and emitted events that others might have interest in. This method is thread-safe.

◆ execLoop()

FuncResult sen::kernel::RunApi::execLoop ( Duration cycleTime,
std::function< void()> && func = nullptr,
bool logOverruns = true )
nodiscard

A basic execution loop. Func is an optional callback that will be invoked on each cycle. logOverruns keeps the log lines for a missed deadline: an execution time overrun and the two ways a cycle is lost. The Tracy messages are emitted either way.

◆ getStartTime()

TimeStamp sen::kernel::RunApi::getStartTime ( ) const
nodiscardnoexcept

The initial simulation time for the objects in the component.

◆ getTime()

TimeStamp sen::kernel::RunApi::getTime ( ) const
nodiscardnoexcept

The (potentially virtualized) time.

◆ getTargetCycleTime()

std::optional< Duration > sen::kernel::RunApi::getTargetCycleTime ( ) const
nodiscardnoexcept

If present, it returns the configured cycle time for iterations.

◆ fetchComponentMonitoringInfo()

ComponentMonitoringInfo sen::kernel::RunApi::fetchComponentMonitoringInfo ( ) const
nodiscard

Monitoring information of the calling component.

◆ fetchMonitoringInfo()

KernelMonitoringInfo sen::kernel::RunApi::fetchMonitoringInfo ( ) const
nodiscard

Monitoring information of all components loaded by the kernel.

◆ getImportedPackages()

Span< const ComponentInfo > sen::kernel::RunApi::getImportedPackages ( ) const
nodiscardnoexcept

Build information for all imported packages (from pipeline components). The returned span references kernel-owned storage that is stable for the lifetime of the kernel.

◆ getLoadedComponents()

Span< const ComponentInfo > sen::kernel::RunApi::getLoadedComponents ( ) const
nodiscardnoexcept

Build information for every component loaded into the kernel, excluding pipeline components (which are built from imports and have no individual build identity) and the internal kernel component. The returned span references kernel-owned storage that is stable for the lifetime of the kernel.

◆ getTransportProtocolVersion()

std::optional< uint32_t > sen::kernel::RunApi::getTransportProtocolVersion ( ) const
nodiscardnoexcept

Version of the currently installed transport protocol. Empty when no transport is installed. Static for the lifetime of the kernel.

◆ getTracer()

Tracer & sen::kernel::RunApi::getTracer ( ) const
nodiscardnoexcept

Create a scoped zone used for tracing runtime performance.

◆ getConfig()

const VarMap & sen::kernel::ConfigGetter::getConfig ( ) const
nodiscardnoexceptinherited

Gets the configuration associated with this component.

◆ getTypes()

CustomTypeRegistry & sen::kernel::KernelApi::getTypes ( )
nodiscardnoexceptinherited

The types registered into the kernel.

◆ requestKernelStop()

void sen::kernel::KernelApi::requestKernelStop ( int exitCode = 0)
inherited

Issues an asynchronous request to stop the kernel. The request is ignored if a previous stop request was issued.

◆ getSource() [1/2]

std::shared_ptr< ObjectSource > sen::kernel::KernelApi::getSource ( const BusAddress & address)
nodiscardinherited

Gets an object source, where objects can be found and published.

◆ getSource() [2/2]

std::shared_ptr< ObjectSource > sen::kernel::KernelApi::getSource ( const std::string & address)
nodiscardinherited

Gets an object source, where objects can be found and published. The address parameter must be given as <session-name>.<bus-name>.

◆ getSessionsDiscoverer()

SessionsDiscoverer & sen::kernel::KernelApi::getSessionsDiscoverer ( )
nodiscardnoexceptinherited

Object that allows discovering sessions and buses.

◆ fetchOwnerInfo()

const ProcessInfo * sen::kernel::KernelApi::fetchOwnerInfo ( const Object * object) const
nodiscardnoexceptinherited

Gets information about the process where an object is. Returns nullptr if the object resides in the current process.

◆ getAppName()

const std::string & sen::kernel::KernelApi::getAppName ( ) const
nodiscardnoexceptinherited

Gets the (optional) application name passed to the kernel as a configuration parameter.

◆ getConfiguredBusAddresses()

std::vector< BusAddress > sen::kernel::KernelApi::getConfiguredBusAddresses ( ) const
nodiscardinherited

Gets configured non-local bus addresses.

◆ getWorkQueue()

::sen::impl::WorkQueue * sen::kernel::KernelApi::getWorkQueue ( ) const
nodiscardnoexceptinherited

The work queue of this runner.

◆ selectAllFrom() [1/2]

template<typename T, typename Bus>
std::shared_ptr< Subscription< T > > sen::kernel::KernelApi::selectAllFrom ( const Bus & bus)
inlinenodiscardinherited

Subscribe to every object of type T on bus. The returned Subscription owns the kernel-side wiring; destruct it to stop.

Callback lifetime (this overload, the next, and selectFrom): onAdded / onRemoved fire on the kernel's run() thread between subscribe and the Subscription's destruction. References they capture must outlive the Subscription. Capture state by shared_ptr or via a component member.

◆ selectAllFrom() [2/2]

template<typename T, typename Bus>
std::shared_ptr< Subscription< T > > sen::kernel::KernelApi::selectAllFrom ( const Bus & bus,
typename sen::ObjectList< T >::Callback onAdded,
typename sen::ObjectList< T >::Callback onRemoved = nullptr )
inlinenodiscardinherited

As above, plus addition/removal callbacks installed before subscribing so they fire for objects already present. Pass nullptr to skip either.

◆ selectFrom()

template<typename T, typename Bus>
std::shared_ptr< Subscription< T > > sen::kernel::KernelApi::selectFrom ( const Bus & bus,
const std::string & query,
typename sen::ObjectList< T >::Callback onAdded = nullptr,
typename sen::ObjectList< T >::Callback onRemoved = nullptr )
inlinenodiscardinherited

Subscription against an arbitrary Sen query (with WHERE conditions). Example: selectFrom<Shape>(bus, R"(SELECT Shape FROM local.bus WHERE color IN ("red"))"). Installs the callbacks before subscribing. Pass nullptr to skip either.

◆ getConfigFilePath()

std::filesystem::path sen::kernel::KernelApi::getConfigFilePath ( ) const
inlinenodiscardnoexceptinherited

Gets the path to the configuration file used to construct the kernel. It might be empty if the kernel is programmatically configured.

◆ getOrCreateLogger()

std::shared_ptr< spdlog::logger > sen::kernel::KernelApi::getOrCreateLogger ( const std::string & loggerName)
staticnodiscardinherited

Registers a new logger in the kernel if it does not exist, or returns the existing one by name. Used to propagate the logger configuration to other packages/components that use it.

◆ applyToAllLoggers()

void sen::kernel::KernelApi::applyToAllLoggers ( std::function< void(std::shared_ptr< spdlog::logger >)> && func)
staticinherited

Applies the input function to all loggers kept in the logger registry. Used by the logmaster component.

func runs under spdlog's logger-map mutex, which is not recursive, so it must not do anything that reaches the registry again. getOrCreateLogger, spdlog::get, setAllLoggersLevel and logging through a logger looked up by name all take that mutex, and calling one from inside func deadlocks the calling thread. Emitting through a logger func was handed is fine.

◆ addLoggerSink()

Result< LoggerSinkRegistration, ExecError > sen::kernel::KernelApi::addLoggerSink ( std::shared_ptr< spdlog::sinks::sink > sink,
TerminalOwnership terminal = TerminalOwnership::shared )
staticnodiscardinherited

Sends every logger's output to sink, including loggers made afterwards.

A component cannot do this by walking the registry itself: spdlog iterates a logger's sink vector without a lock and hands out a bare reference, so appending to a logger another thread is emitting through is a use-after-free. Appending earlier is no safer, because the kernel starts each group's threads before it loads the next group and logs between groups itself. The kernel therefore attaches one sink of its own to every logger, in the only window where attaching is safe, and this call registers sink behind it under a mutex. No logger's sink vector is touched here, so it may be called from any thread at any time.

sink keeps its own pattern: the relay hands on the unformatted message and each registered sink formats it.

The registration has no owner. Sinks are held until removed, so a component that is unloaded must call removeLoggerSink, and it must stop its sink reaching its own state first, because the sink can be running on another thread. Nothing here enforces that order: this is a static function with no api object, so the kernel cannot know which component registered what.

A sink left registered is a state hazard rather than a code one only because nothing dlcloses a component, so its code stays mapped. If unload is ever made to really unload, every un-removed sink becomes a jump into unmapped memory on the next log line.

Returns what the registration did, or an error if sink is null. Nothing else can fail.

◆ removeLoggerSink()

FuncResult sen::kernel::KernelApi::removeLoggerSink ( const std::shared_ptr< spdlog::sinks::sink > & sink)
staticnodiscardinherited

Stops sending output to sink. Restores the console sinks if this was the last registered sink claiming the terminal. For a component being unloaded.

Removing a sink that was never registered is not an error. A null sink is.

◆ setAllLoggersLevel()

FuncResult sen::kernel::KernelApi::setAllLoggersLevel ( spdlog::level::level_enum level)
staticnodiscardinherited

Sets the level on every logger the kernel knows and on every logger made afterwards.

Walking the registry with applyToAllLoggers reaches only the loggers that exist when it runs, so a level set that way stops applying as soon as another component makes a logger. This sets the registry's own level, which is what a new logger is initialised from.

It replaces the per-logger levels a configuration file asked for, and there is no way back to them: read one before you change it if you mean to restore it.

Errors on a level outside the enum. Nothing else can fail.

◆ setCrashBannerDescriptor()

void sen::kernel::KernelApi::setCrashBannerDescriptor ( int descriptor)
staticnoexceptinherited

Where the kernel writes the crash banner, the few lines naming what died and where the report went, for a component that has taken stderr over.

A component that draws a full-screen terminal captures stderr so a stray write cannot land on its display. That captures the crash banner too, and a fatal error would print the report's path into a pipe that dies with the process, leaving the user with a vanished UI and an exit status. Hand over the descriptor the component saved and the banner goes there. Pass -1 to restore stderr, which a component must do before the descriptor it gave is closed.

◆ prepareCurrentThreadForCrashReports()

void sen::kernel::KernelApi::prepareCurrentThreadForCrashReports ( )
staticnoexceptinherited

Give the calling thread the alternate signal stack the crash handler needs.

Every thread the kernel creates gets this when it starts. A component that creates its own thread with std::thread does not, and a fatal signal on such a thread, a stack overflow in particular, can fault again inside the handler and produce no dump at all. Call it once, first thing, in any thread the component starts itself. Harmless if crash reporting is disabled or already armed.

◆ getAllLoggersLevel()

spdlog::level::level_enum sen::kernel::KernelApi::getAllLoggersLevel ( )
staticnodiscardinherited

The level setAllLoggersLevel last set, which is also the level a new logger starts from.

Read this rather than keeping a copy beside the setter, which drifts as soon as anything else sets the level.

◆ impl::remoteProcessDetected

void impl::remoteProcessDetected ( RunApi & api,
const ProcessInfo & processInfo )
friend

◆ impl::remoteProcessLost

void impl::remoteProcessLost ( RunApi & api,
const ProcessInfo & processInfo )
friend

The documentation for this class was generated from the following file: