1#ifndef LINTEL_EVENTBUS_H
2#define LINTEL_EVENTBUS_H
195 static constexpr std::size_t CACHE_LINE = 64;
198 struct alignas(CACHE_LINE)
Slot
200 std::atomic<std::uint64_t> sequence{ 0 };
216 ShmRing(
const ShmRing &) =
delete;
217 ShmRing &operator=(
const ShmRing &) =
delete;
222 bool push(
const Event &event);
227 bool pop(
Event &out);
231 [[nodiscard]]
bool empty()
const;
234 [[nodiscard]]
static bool isLockFree();
237 std::atomic<std::uint64_t> m_head{ 0 };
238 std::byte m_headPadding[CACHE_LINE -
sizeof(std::uint64_t)]{};
239 std::atomic<std::uint64_t> m_tail{ 0 };
240 std::byte m_tailPadding[CACHE_LINE -
sizeof(std::uint64_t)]{};
241 std::size_t m_capacity = 0;
242 ShmSegmentAccessor m_segment;
243 std::byte *m_allocation =
nullptr;
244 std::int64_t m_bufferOffset = 0;
246 [[nodiscard]] Slot *buffer();
247 [[nodiscard]]
const Slot *buffer()
const;
253 char name[Event::NAME_SIZE]{};
254 std::atomic<std::size_t> subscriberCount{ 0 };
255 std::size_t subscribers[EventBusLimits::MAX_SUBSCRIBERS]{};
259 struct SubscriberEntry
261 char name[Event::NAME_SIZE]{};
262 std::atomic<bool> active{
false };
263 std::atomic<std::size_t> topicRefCount{ 0 };
277 void acquire()
const;
280 void release()
const;
283 static constexpr std::uint64_t STALE_THRESHOLD_MS = 500;
284 static constexpr std::uint64_t TIMESTAMP_MASK = 0xFFFFFFFFu;
286 mutable std::atomic<std::uint64_t> m_state;
288 static std::uint64_t ownerId();
289 static std::uint64_t nowMs();
290 static bool isStale(std::uint64_t state);
291 static std::uint64_t encode();
295 std::size_t m_busCapacity = 0;
296 std::size_t m_subscriberCapacity = 0;
297 std::size_t m_maxTopics = 0;
298 std::size_t m_maxSubscribers = 0;
299 std::atomic<std::int64_t> m_sequence{ 0 };
300 std::atomic<std::uint64_t> m_droppedEvents{ 0 };
301 std::atomic<std::size_t> m_topicCount{ 0 };
302 std::atomic<std::size_t> m_subscriberCount{ 0 };
303 RegistryLock m_registryLock;
309 [[
nodiscard]]
int findTopicIndex(
const char *topic)
const;
312 [[
nodiscard]]
const ShmRing &subscriberQueueOf(std::size_t
index)
const;
315 [[
nodiscard]]
static bool nameEquals(
const char *
lhs,
const char *
rhs);
329 [[nodiscard]]
virtual const char *
getName()
const = 0;
353 virtual bool subscribe(
const std::string &topic,
const std::string &subscriber) = 0;
359 virtual bool unsubscribe(
const std::string &topic,
const std::string &subscriber) = 0;
364 [[nodiscard]]
virtual bool isSubscribed(
const std::string &topic,
const std::string &subscriber)
const = 0;
385 [[nodiscard]]
virtual std::optional<Event>
receive() = 0;
390 [[nodiscard]]
virtual std::optional<Event>
receiveOf(
const std::string &subscriber) = 0;
393 [[nodiscard]]
virtual bool isEmpty()
const = 0;
397 [[nodiscard]]
virtual bool isEmptyOf(
const std::string &subscriber)
const = 0;
417 [[nodiscard]]
const char *
getName()
const override {
return m_bus.getName(); }
421 [[nodiscard]]
bool isLockFree()
const override {
return m_bus.isLockFree(); }
423 bool registerTopic(
const std::string &topic)
override {
return m_bus.registerTopic(topic); }
427 return m_bus.isTopicRegistered(topic);
430 [[nodiscard]] std::size_t
topicCount()
const override {
return m_bus.topicCount(); }
432 bool subscribe(
const std::string &topic,
const std::string &subscriber)
override
434 return m_bus.subscribe(topic, subscriber);
437 bool unsubscribe(
const std::string &topic,
const std::string &subscriber)
override
439 return m_bus.unsubscribe(topic, subscriber);
442 [[nodiscard]]
bool isSubscribed(
const std::string &topic,
const std::string &subscriber)
const override
444 return m_bus.isSubscribed(topic, subscriber);
449 return m_bus.numberOfSubscribersOf(topic);
452 [[nodiscard]] std::size_t
subscriberCount()
const override {
return m_bus.subscriberCount(); }
454 bool publish(
const Event &event)
override {
return m_bus.publish(event); }
458 [[nodiscard]] std::optional<Event>
receive()
override {
return m_bus.receive(); }
460 [[nodiscard]] std::optional<Event>
receiveOf(
const std::string &subscriber)
override
462 return m_bus.receiveOf(subscriber);
465 [[nodiscard]]
bool isEmpty()
const override {
return m_bus.isEmpty(); }
467 [[nodiscard]]
bool isEmptyOf(
const std::string &subscriber)
const override {
return m_bus.isEmptyOf(subscriber); }
469 [[nodiscard]] std::int64_t
sequenceOf()
const override {
return m_bus.sequenceOf(); }
471 [[nodiscard]] std::uint64_t
droppedEventsOf()
const override {
return m_bus.droppedEventsOf(); }
473 void reset()
override { m_bus.reset(); }
Definition EventBus.h:411
void reset() override
Definition EventBus.h:473
bool isSubscribed(const std::string &topic, const std::string &subscriber) const override
Definition EventBus.h:442
bool isTopicRegistered(const std::string &topic) const override
Definition EventBus.h:425
std::size_t subscriberCount() const override
Definition EventBus.h:452
bool isEmptyOf(const std::string &subscriber) const override
Definition EventBus.h:467
std::optional< Event > receive() override
Definition EventBus.h:458
bool subscribe(const std::string &topic, const std::string &subscriber) override
Definition EventBus.h:432
bool registerTopic(const std::string &topic) override
Definition EventBus.h:423
EventBusView(EventBus &bus)
Definition EventBus.h:415
const char * getName() const override
Definition EventBus.h:417
std::int64_t sequenceOf() const override
Definition EventBus.h:469
std::uint64_t droppedEventsOf() const override
Definition EventBus.h:471
EventBusConfig getConfig() const override
Definition EventBus.h:419
bool isLockFree() const override
Definition EventBus.h:421
std::optional< Event > receiveOf(const std::string &subscriber) override
Definition EventBus.h:460
std::size_t numberOfSubscribersOf(const std::string &topic) const override
Definition EventBus.h:447
std::size_t topicCount() const override
Definition EventBus.h:430
bool isEmpty() const override
Definition EventBus.h:465
bool publishToSubscribers(const Event &event) override
Definition EventBus.h:456
bool publish(const Event &event) override
Definition EventBus.h:454
bool unsubscribe(const std::string &topic, const std::string &subscriber) override
Definition EventBus.h:437
std::size_t topicCount() const
bool unsubscribe(const std::string &topic, const std::string &subscriber)
const char * getName() const
std::optional< Event > receiveOf(const std::string &subscriber)
EventBus(const EventBus &)=delete
EventBus & operator=(const EventBus &)=delete
std::int64_t sequenceOf() const
std::optional< Event > receive()
bool registerTopic(const std::string &topic)
bool isEmptyOf(const std::string &subscriber) const
EventBusConfig getConfig() const
bool isTopicRegistered(const std::string &topic) const
bool subscribe(const std::string &topic, const std::string &subscriber)
bool isSubscribed(const std::string &topic, const std::string &subscriber) const
std::uint64_t droppedEventsOf() const
bool publishToSubscribers(const Event &event)
static std::size_t requiredSize(const EventBusConfig &config)
bool publish(const Event &event)
EventBus(const std::string &name, const EventBusConfig &config, ShmSegmentAccessor segment)
std::size_t subscriberCount() const
std::size_t numberOfSubscribersOf(const std::string &topic) const
static constexpr std::size_t NAME_SIZE
Definition Event.h:25
Definition EventBus.h:324
virtual bool isSubscribed(const std::string &topic, const std::string &subscriber) const =0
virtual std::optional< Event > receive()=0
virtual std::uint64_t droppedEventsOf() const =0
virtual bool publishToSubscribers(const Event &event)=0
virtual const char * getName() const =0
virtual bool isTopicRegistered(const std::string &topic) const =0
virtual std::optional< Event > receiveOf(const std::string &subscriber)=0
virtual bool isEmpty() const =0
virtual std::int64_t sequenceOf() const =0
virtual std::size_t numberOfSubscribersOf(const std::string &topic) const =0
virtual bool unsubscribe(const std::string &topic, const std::string &subscriber)=0
virtual ~IEventBus()=default
virtual bool publish(const Event &event)=0
virtual bool isEmptyOf(const std::string &subscriber) const =0
virtual bool subscribe(const std::string &topic, const std::string &subscriber)=0
virtual bool isLockFree() const =0
virtual std::size_t subscriberCount() const =0
virtual std::size_t topicCount() const =0
virtual EventBusConfig getConfig() const =0
virtual bool registerTopic(const std::string &topic)=0
Definition ShmSegmentAccessor.h:21
Definition BaseFeature.h:6
constexpr std::string_view type_name()
Definition TypeName.h:9
std::size_t busCapacity
Definition EventBus.h:33
std::size_t maxTopics
Definition EventBus.h:37
std::size_t maxSubscribers
Definition EventBus.h:39
bool isValid() const
Definition EventBus.h:42
std::size_t subscriberCapacity
Definition EventBus.h:35
static constexpr std::size_t MAX_SUBSCRIBERS
Definition EventBus.h:20
static constexpr std::size_t MAX_CAPACITY
Definition EventBus.h:22
static constexpr std::size_t MAX_TOPICS
Definition EventBus.h:18
Definition EventBus.h:199
Event value
Definition EventBus.h:201