Sen API
Sen Libraries
Loading...
Searching...
No Matches
component_api.h
Go to the documentation of this file.
1// === component_api.h =================================================================================================
2// Sen Infrastructure
3// Released under the Apache License v2.0 (SPDX-License-Identifier Apache-2.0).
4// See the LICENSE.txt file for more information.
5// © Airbus SAS, Airbus Helicopters, and Airbus Defence and Space SAU/GmbH/SAS.
6// =====================================================================================================================
7
8#ifndef SEN_KERNEL_COMPONENT_API_H
9#define SEN_KERNEL_COMPONENT_API_H
10
11// sen
17#include "sen/core/base/span.h"
20#include "sen/core/meta/var.h"
23#include "sen/core/obj/object.h"
27
28// kernel
29#include "sen/kernel/kernel.h"
31#include "sen/kernel/tracer.h"
33
34// generated code
35#include "stl/sen/kernel/basic_types.stl.h"
36#include "stl/sen/kernel/network_footprint.stl.h"
37
38// std
39#include <atomic>
40#include <cstddef>
41#include <cstdint>
42#include <cstring>
43#include <filesystem>
44#include <functional>
45#include <memory>
46#include <optional>
47#include <string>
48#include <string_view>
49#include <type_traits>
50#include <utility>
51#include <vector>
52
53// Declared, not included, so compiling against the kernel needs nothing from spdlog. The same
54// declarations spdlog ships in <spdlog/fwd.h>.
55namespace spdlog
56{
57// NOLINTNEXTLINE(readability-identifier-naming): spdlog's own class name
58class logger;
59
60namespace level
61{
62// NOLINTNEXTLINE(readability-identifier-naming): spdlog's own enum name
63enum level_enum : int;
64} // namespace level
65} // namespace spdlog
66
67namespace sen::kernel
68{
69
72
75
77using NetworkFootprintReporter = NetworkFootprint(Span<const BusAddress>) const;
78
80class RunApi;
81class KernelApi;
82
83namespace impl
84{
85
86class Runner;
87class KernelImpl;
88
89[[nodiscard]] FuncResult execLoop(Runner* runner,
90 Duration cycleTime,
91 std::function<void()>&& workFunction,
92 bool logOverruns);
93
94void installTransportFactory(KernelImpl* kernel, TransportFactory&& factory, uint32_t transportVersion);
95
96void remoteProcessDetected(RunApi& api, const ProcessInfo& processInfo);
97
98void remoteProcessLost(RunApi& api, const ProcessInfo& processInfo);
99
100[[nodiscard]] std::shared_ptr<ObjectSource> getSource(Runner* runner, const BusAddress& address);
101
102[[nodiscard]] SessionsDiscoverer& getSessionsDiscoverer(Runner* runner);
103
104[[nodiscard]] const ProcessInfo* fetchOwnerInfo(const Object* object);
105
106[[nodiscard]] ::sen::impl::WorkQueue* getWorkQueue(Runner* runner);
107
108[[nodiscard]] std::shared_ptr<spdlog::logger> getOrCreateLogger(const std::string& loggerName);
109
110void applyToAllLoggers(std::function<void(std::shared_ptr<spdlog::logger>)>&& func);
111
112[[nodiscard]] FuncResult setAllLoggersLevel(spdlog::level::level_enum level);
113
114[[nodiscard]] spdlog::level::level_enum getAllLoggersLevel();
115
116void setCrashBannerDescriptor(int descriptor) noexcept;
117
118void prepareCurrentThreadForCrashReports() noexcept;
119
120} // namespace impl
121
124{
125 std::string name;
126 uint32_t group = 0;
127 bool requiresRealTime = false;
128 std::optional<Duration> cycleTime;
129 std::size_t objectCount = 0;
133 std::optional<Duration> lastCycleExecutionCpuTime;
134
138 std::optional<Duration> lastCycleComponentCpuTime;
139
143 std::optional<Duration> lastCycleQueuedWorkCpuTime;
144
148 std::optional<Duration> worstCycleExecutionCpuTime;
149
151 std::optional<Duration> worstCycleComponentCpuTime;
152
156 std::optional<Duration> lastCycleStartDelay;
157
160 std::optional<Duration> worstStartDelay;
161
166 std::optional<uint64_t> overrunCount;
167
173 std::optional<uint64_t> missedFrameCount;
174
179 std::optional<uint64_t> oversleptCount;
180};
181
184{
185 RunMode runMode = RunMode::realTime;
187 std::vector<ComponentMonitoringInfo> components;
188};
189
192{
193public:
194 KernelApi(Kernel& kernel, impl::Runner* runner) noexcept;
195
196public:
198 [[nodiscard]] CustomTypeRegistry& getTypes() noexcept;
199
202 void requestKernelStop(int exitCode = 0);
203
205 [[nodiscard]] std::shared_ptr<ObjectSource> getSource(const BusAddress& address);
206
209 [[nodiscard]] std::shared_ptr<ObjectSource> getSource(const std::string& address);
210
212 [[nodiscard]] SessionsDiscoverer& getSessionsDiscoverer() noexcept;
213
216 [[nodiscard]] const ProcessInfo* fetchOwnerInfo(const Object* object) const noexcept;
217
219 [[nodiscard]] const std::string& getAppName() const noexcept;
220
222 [[nodiscard]] std::vector<BusAddress> getConfiguredBusAddresses() const;
223
225 [[nodiscard]] ::sen::impl::WorkQueue* getWorkQueue() const noexcept;
226
234 template <typename T, typename Bus>
235 [[nodiscard]] std::shared_ptr<Subscription<T>> selectAllFrom(const Bus& bus);
236
239 template <typename T, typename Bus>
240 [[nodiscard]] std::shared_ptr<Subscription<T>> selectAllFrom(
241 const Bus& bus,
242 typename sen::ObjectList<T>::Callback onAdded,
243 typename sen::ObjectList<T>::Callback onRemoved = nullptr);
244
248 template <typename T, typename Bus>
249 [[nodiscard]] std::shared_ptr<Subscription<T>> selectFrom(const Bus& bus,
250 const std::string& query,
251 typename sen::ObjectList<T>::Callback onAdded = nullptr,
252 typename sen::ObjectList<T>::Callback onRemoved = nullptr);
253
256 [[nodiscard]] std::filesystem::path getConfigFilePath() const noexcept { return kernel_.getConfigPath(); }
257
260 [[nodiscard]] static std::shared_ptr<spdlog::logger> getOrCreateLogger(const std::string& loggerName);
261
269 static void applyToAllLoggers(std::function<void(std::shared_ptr<spdlog::logger>)>&& func);
270
289 [[nodiscard]] static FuncResult setAllLoggersLevel(spdlog::level::level_enum level);
290
299 static void setCrashBannerDescriptor(int descriptor) noexcept;
300
308
313 [[nodiscard]] static spdlog::level::level_enum getAllLoggersLevel();
314
315private:
316 template <typename T>
317 [[nodiscard]] std::string buildQuery(const BusAddress& address) const;
318
319 template <typename T>
320 [[nodiscard]] std::string buildQuery(std::string_view bus) const;
321
322private:
323 Kernel& kernel_;
324 impl::Runner* runner_;
325};
326
329{
330public:
331 explicit ConfigGetter(const VarMap& config) noexcept;
332
333public:
335 [[nodiscard]] const VarMap& getConfig() const noexcept;
336
337private:
338 const VarMap& config_;
339};
340
343{
344public:
345 SEN_NOCOPY_NOMOVE(RegistrationApi)
346
347public:
348 RegistrationApi(Kernel& kernel, impl::Runner* runner, const VarMap& config) noexcept;
349 ~RegistrationApi() noexcept = default;
350};
351
353class PreloadApi: public ConfigGetter, public KernelApi
354{
355 SEN_NOCOPY_NOMOVE(PreloadApi)
356
357public:
358 PreloadApi(Kernel& kernel, impl::Runner* runner, const VarMap& config) noexcept;
359
360 ~PreloadApi() noexcept = default;
361
362public:
364 void installTransportFactory(TransportFactory&& factory, uint32_t transportVersion) const;
365
367 void installTracerFactory(TracerFactory&& factory) const;
368
371 void installFootprintReporter(sen::std_util::move_only_function<NetworkFootprintReporter>&& reporter);
372
374 void installFootprintReporter(sen::std_util::move_only_function<NetworkFootprintReporter>&& offlineReporter,
375 sen::std_util::move_only_function<NetworkFootprint() const>&& runtimeReporter);
376
377private:
378 Kernel& kernel_;
379};
380
382class LoadApi: public ConfigGetter, public KernelApi
383{
384 SEN_NOCOPY_NOMOVE(LoadApi)
385
386public:
387 LoadApi(Kernel& kernel, impl::Runner* runner, const VarMap& config) noexcept;
388
389 ~LoadApi() noexcept = default;
390};
391
393class InitApi: public ConfigGetter, public KernelApi
394{
395 SEN_NOCOPY_NOMOVE(InitApi)
396
397public:
398 InitApi(Kernel& kernel, impl::Runner* runner, const VarMap& config) noexcept;
399
400 ~InitApi() noexcept = default;
401};
402
404class RunApi: public ConfigGetter, public KernelApi
405{
406public:
407 SEN_NOCOPY_NOMOVE(RunApi)
408
409public:
411 impl::KernelImpl& kernelImpl,
412 impl::Runner* runner,
413 std::atomic_bool& stopRequested,
414 const VarMap& config,
415 Guarded<TimeStamp>& timePoint) noexcept;
416
417 ~RunApi() noexcept = default;
418
419public:
421 [[nodiscard]] const std::atomic_bool& stopRequested() const noexcept;
422
427
429 void update();
430
435 void commit();
436
442 void commit(TimeStamp time);
443
448 [[nodiscard]] FuncResult execLoop(Duration cycleTime,
449 std::function<void()>&& func = nullptr,
450 bool logOverruns = true);
451
453 [[nodiscard]] TimeStamp getStartTime() const noexcept;
454
456 [[nodiscard]] TimeStamp getTime() const noexcept;
457
459 [[nodiscard]] std::optional<Duration> getTargetCycleTime() const noexcept;
460
463
466
470 [[nodiscard]] Span<const ComponentInfo> getImportedPackages() const noexcept;
471
477 [[nodiscard]] Span<const ComponentInfo> getLoadedComponents() const noexcept;
478
481 [[nodiscard]] std::optional<uint32_t> getTransportProtocolVersion() const noexcept;
482
484 [[nodiscard]] Tracer& getTracer() const noexcept;
485
486private:
487 friend void impl::remoteProcessDetected(RunApi& api, const ProcessInfo& processInfo);
488
489 friend void impl::remoteProcessLost(RunApi& api, const ProcessInfo& processInfo);
490
491private:
492 impl::KernelImpl& kernelImpl_;
493 impl::Runner* runner_;
494 std::atomic_bool& stopRequested_;
495 Guarded<TimeStamp>& timePoint_;
496};
497
499class UnloadApi: public ConfigGetter, public KernelApi
500{
501 SEN_NOCOPY_NOMOVE(UnloadApi)
502
503public:
504 UnloadApi(Kernel& kernel, const VarMap& config, impl::Runner* runner) noexcept;
505 ~UnloadApi() noexcept = default;
506};
507
508//----------------------------------------------------------------------------------------------------------------------
509// Inline implementation
510//----------------------------------------------------------------------------------------------------------------------
511
512template <typename T, typename Bus>
513inline std::shared_ptr<Subscription<T>> KernelApi::selectAllFrom(const Bus& bus)
514{
515 auto sub = std::make_shared<Subscription<T>>();
516 sub->attachTo(getSource(bus), Interest::make(buildQuery<T>(bus), getTypes()), true);
517 return sub;
518}
519
520template <typename T, typename Bus>
521inline std::shared_ptr<Subscription<T>> KernelApi::selectAllFrom(const Bus& bus,
522 typename ObjectList<T>::Callback onAdded,
523 typename ObjectList<T>::Callback onRemoved)
524{
525 auto sub = std::make_shared<Subscription<T>>();
526 // Install callbacks before subscribing so they fire for objects already present.
527 if (onAdded)
528 {
529 std::ignore = sub->list.onAdded(std::move(onAdded));
530 }
531 if (onRemoved)
532 {
533 std::ignore = sub->list.onRemoved(std::move(onRemoved));
534 }
535 sub->attachTo(getSource(bus), Interest::make(buildQuery<T>(bus), getTypes()), true);
536 return sub;
537}
538
539template <typename T, typename Bus>
540inline std::shared_ptr<Subscription<T>> KernelApi::selectFrom(const Bus& bus,
541 const std::string& query,
542 typename sen::ObjectList<T>::Callback onAdded,
543 typename sen::ObjectList<T>::Callback onRemoved)
544{
545 auto sub = std::make_shared<Subscription<T>>();
546
547 // Install callbacks before subscribing so they fire for objects already present.
548 if (onAdded)
549 {
550 std::ignore = sub->list.onAdded(std::move(onAdded));
551 }
552 if (onRemoved)
553 {
554 std::ignore = sub->list.onRemoved(std::move(onRemoved));
555 }
556 sub->attachTo(getSource(bus), Interest::make(query, getTypes()), true);
557 return sub;
558}
559
560namespace impl
561{
562
566template <typename T>
567[[nodiscard]] inline std::string_view queryTypeName()
568{
569 if constexpr (std::is_same_v<T, Object>)
570 {
571 return "*";
572 }
573 else
574 {
575 static_assert(std::is_same_v<decltype(T::meta()), ::sen::ConstTypeHandle<::sen::ClassType>>,
576 "a subscription type must be a Sen object class");
577 return T::meta()->getQualifiedName();
578 }
579}
580
581} // namespace impl
582
583template <typename T>
584inline std::string KernelApi::buildQuery(const BusAddress& address) const
585{
586 std::string query = "SELECT ";
587 query.append(impl::queryTypeName<T>());
588 query.append(" FROM ");
589 query.append(address.sessionName);
590 query.append(".");
591 query.append(address.busName);
592
593 return query;
594}
595
596template <typename T>
597inline std::string KernelApi::buildQuery(std::string_view bus) const
598{
599 std::string query = "SELECT ";
600 query.append(impl::queryTypeName<T>());
601 query.append(" FROM ");
602 query.append(bus);
603
604 return query;
605}
606
607} // namespace sen::kernel
608
609#endif // SEN_KERNEL_COMPONENT_API_H
Base class for event or method callbacks. It stores the queue where to push the response....
Definition callback.h:146
A registry of custom types.
Definition type_registry.h:36
A time duration.
Definition duration.h:25
static std::shared_ptr< Interest > make(std::string_view query, const CustomTypeRegistry &typeRegistry)
Make an interest from a query. Throws std::exception if not well formed.
A sen object.
Definition object.h:76
A list of objects that is managed by some source based on user-expressed interests.
Definition object_list.h:30
std::function< void(const Iterators &iterators)> Callback
Definition object_list.h:70
Allows adding and receiving objects.
Definition object_source.h:35
Result<T, E> is a template type that can be used to return and propagate errors. The intent is to rep...
Definition result.h:135
Contiguous view of elements of type T. Inspired by http://www.open-std.org/jtc1/sc22/wg21/docs/papers...
Definition span.h:34
A point in time.
Definition timestamp.h:26
ConfigGetter(const VarMap &config) noexcept
const VarMap & getConfig() const noexcept
Gets the configuration associated with this component.
~InitApi() noexcept=default
InitApi(Kernel &kernel, impl::Runner *runner, const VarMap &config) noexcept
User-facing kernel functions.
Definition component_api.h:192
::sen::impl::WorkQueue * getWorkQueue() const noexcept
The work queue of this runner.
KernelApi(Kernel &kernel, impl::Runner *runner) noexcept
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,...
Definition component_api.h:540
std::shared_ptr< ObjectSource > getSource(const BusAddress &address)
Gets an object source, where objects can be found and published.
static FuncResult setAllLoggersLevel(spdlog::level::level_enum level)
The level below is the registry's, not a kernel's, and spdlog is one shared library with one registry...
static void prepareCurrentThreadForCrashReports() noexcept
Give the calling thread the alternate signal stack the crash handler needs.
static void setCrashBannerDescriptor(int descriptor) noexcept
Where the kernel writes the crash banner, the few lines naming what died and where the report went,...
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...
Definition component_api.h:256
CustomTypeRegistry & getTypes() noexcept
The types registered into the kernel.
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....
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 c...
const std::string & getAppName() const noexcept
Gets the (optional) application name passed to the kernel as a configuration parameter.
static spdlog::level::level_enum getAllLoggersLevel()
The level setAllLoggersLevel last set, which is also the level a new logger starts from.
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 componen...
std::vector< BusAddress > getConfiguredBusAddresses() const
Gets configured non-local bus addresses.
void requestKernelStop(int exitCode=0)
Issues an asynchronous request to stop the kernel. The request is ignored if a previous stop request ...
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; de...
Definition component_api.h:513
Main entry point of a sen microkernel.
Definition kernel.h:43
~LoadApi() noexcept=default
LoadApi(Kernel &kernel, impl::Runner *runner, const VarMap &config) noexcept
PreloadApi(Kernel &kernel, impl::Runner *runner, const VarMap &config) noexcept
void installFootprintReporter(sen::std_util::move_only_function< NetworkFootprintReporter > &&reporter)
Installs a footprint reporter. The kernel stores a single reporter, installing another replaces the e...
~PreloadApi() noexcept=default
void installTracerFactory(TracerFactory &&factory) const
Installs a tracer factory.
void installTransportFactory(TransportFactory &&factory, uint32_t transportVersion) const
Installs a transport factory for the kernel to use for sessions.
RegistrationApi(Kernel &kernel, impl::Runner *runner, const VarMap &config) noexcept
~RegistrationApi() noexcept=default
What can be done while a component is running.
Definition component_api.h:405
Span< const ComponentInfo > getLoadedComponents() const noexcept
Build information for every component loaded into the kernel, excluding pipeline components (which ar...
TimeStamp getStartTime() const noexcept
The initial simulation time for the objects in the component.
Span< const ComponentInfo > getImportedPackages() const noexcept
Build information for all imported packages (from pipeline components). The returned span references ...
void commit()
Send changes, so that they become visible to other participants. This includes object additions and r...
Tracer & getTracer() const noexcept
Create a scoped zone used for tracing runtime performance.
void drainInputs()
Perform any request coming from the outside and drainInputs all the local data structures with their ...
ComponentMonitoringInfo fetchComponentMonitoringInfo() const
Monitoring information of the calling component.
~RunApi() noexcept=default
std::optional< Duration > getTargetCycleTime() const noexcept
If present, it returns the configured cycle time for iterations.
std::optional< uint32_t > getTransportProtocolVersion() const noexcept
Version of the currently installed transport protocol. Empty when no transport is installed....
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....
RunApi(Kernel &kernel, impl::KernelImpl &kernelImpl, impl::Runner *runner, std::atomic_bool &stopRequested, const VarMap &config, Guarded< TimeStamp > &timePoint) noexcept
KernelMonitoringInfo fetchMonitoringInfo() const
Monitoring information of all components loaded by the kernel.
friend void impl::remoteProcessLost(RunApi &api, const ProcessInfo &processInfo)
const std::atomic_bool & stopRequested() const noexcept
True if stop has been requested by the runtime.
void update()
This calls update() on all the objects registered by the component.
friend void impl::remoteProcessDetected(RunApi &api, const ProcessInfo &processInfo)
TimeStamp getTime() const noexcept
The (potentially virtualized) time.
Definition source_info.h:99
Interface implemented by tracers. You can use it to trace the behavior of your code....
Definition tracer.h:28
UnloadApi(Kernel &kernel, const VarMap &config, impl::Runner *runner) noexcept
~UnloadApi() noexcept=default
std::function< std::unique_ptr< Transport >(const std::string &, std::unique_ptr< Tracer > tracer)> TransportFactory
A function that creates a transport given a session name.
Definition include/sen/kernel/transport.h:203
Global transport statistics.
Definition include/sen/kernel/transport.h:146
std::map< std::string, Var, std::less<> > VarMap
A map of vars to represent structures.
Definition var.h:107
TypeHandle< const T > ConstTypeHandle
Definition type.h:319
Strong type for the unique identifier for a transport timer.
Definition native_object_impl.h:39
std::optional< Duration > lastCycleExecutionCpuTime
Thread CPU time, user and system, consumed by the last completed execution cycle. On Windows every CP...
Definition component_api.h:133
std::optional< Duration > lastCycleStartDelay
How late the thread woke for the cycle it was waiting for. The scheduler's contribution,...
Definition component_api.h:156
std::optional< Duration > lastCycleQueuedWorkCpuTime
The part of that spent on work queued on the component: the callbacks it registered,...
Definition component_api.h:143
uint32_t group
Definition component_api.h:126
Result< OpState, ExecError > PassResult
The result of operations that may be called multiple times.
Definition component_api.h:74
std::optional< Duration > worstStartDelay
The latest the thread has ever woken. A machine that is late once in a thousand cycles rarely has it ...
Definition component_api.h:160
std::function< std::unique_ptr< Tracer >(std::string_view)> TracerFactory
A factory function for tracers.
Definition tracer.h:119
std::optional< uint64_t > overrunCount
Cycles whose execution used more CPU time than the period. A cycle that blocked rather than computed ...
Definition component_api.h:166
Result< void, ExecError > FuncResult
The result of operations that are called once.
Definition component_api.h:71
std::optional< Duration > cycleTime
Definition component_api.h:128
std::vector< ComponentMonitoringInfo > components
Definition component_api.h:187
std::optional< uint64_t > oversleptCount
Cycles lost because the sleep returned late, so the component was not running when it should have bee...
Definition component_api.h:179
std::size_t objectCount
Definition component_api.h:129
std::string name
Definition component_api.h:125
std::optional< Duration > lastCycleComponentCpuTime
The part of that spent in the component's own code: its objects' update() and its work function....
Definition component_api.h:138
std::optional< Duration > worstCycleComponentCpuTime
The component's share of that same worst cycle, so the two can be compared.
Definition component_api.h:151
RunMode runMode
Definition component_api.h:185
std::optional< uint64_t > missedFrameCount
Cycles lost because the work finished after the cycle it belonged to. Every lost cycle is counted,...
Definition component_api.h:173
NetworkFootprint(Span< const BusAddress >) const NetworkFootprintReporter
Callable that builds a network footprint from bus addresses.
Definition component_api.h:77
bool requiresRealTime
Definition component_api.h:127
std::optional< Duration > worstCycleExecutionCpuTime
The most CPU time any one cycle has used since the component started running, leaving out its first c...
Definition component_api.h:148
TransportStats transportStats
Definition component_api.h:186
Runtime monitoring information about a single component runner.
Definition component_api.h:124
Kernel runtime monitoring information.
Definition component_api.h:184
Definition bits.h:26
Definition assert.h:19
Definition component_api.h:61
Definition component_api.h:56
STL namespace.
Guarded is a lightweight wrapper class that can be used to protect an objet of type T from concurrent...
Definition mutex_utils.h:49
A list of objects and a reference to its source (to keep it alive).
Definition subscription.h:29