Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#550] custom event ids #552

Merged
merged 13 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ Adjusting `global` settings ensures a non-interfering setup.
* `defaults.event.max-nodes` - [int]: Maximum number of nodes.
* `defaults.event.event-id-max-value` - [int]: Greatest value an [`EventId`] can
have.
* `defaults.event.notifier-created-event` - [Option\<int\>]: If defined,
it defines the event id that is emitted when a new notifier is created.
* `defaults.event.notifier-dropped-event` - [Option\<int\>]: If defined,
it defines the event id that is emitted when a notifier is destroyed.
* `defaults.event.notifier-dead-event` - [Option\<int\>]: If defined,
it defines the event id that is emitted when a dead notifier is cleaned up.

### Service: Publish Subscribe Messaging Pattern

Expand Down
3 changes: 3 additions & 0 deletions config/iceoryx2.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,6 @@ max-listeners = 16
max-notifiers = 16
max-nodes = 36
event-id-max-value = 4294967295
# notifier-created-event = 1 # uncomment to enable setting
# notifier-dropped-event = 2 # uncomment to enable setting
# notifier-dead-event = 3 # uncomment to enable setting
1 change: 1 addition & 0 deletions doc/release-notes/iceoryx2-unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
* Make signal handling optional in `WaitSet` and `Node` [#528](https://github.com/eclipse-iceoryx/iceoryx2/issues/528)
* Support dynamic data with reallocation for publish-subscribe communication [#532](https://github.com/eclipse-iceoryx/iceoryx2/issues/532)
* Add benchmark for iceoryx2 queues [#535](https://github.com/eclipse-iceoryx/iceoryx2/issues/535)
* Add auto event mission for create, drop and dead notifiers [#550](https://github.com/eclipse-iceoryx/iceoryx2/issues/550)

### Bugfixes

Expand Down
10 changes: 10 additions & 0 deletions iceoryx2-ffi/cxx/include/iox/builder_addendum.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@

// NOLINTBEGIN(cppcoreguidelines-macro-usage)
// NOLINTBEGIN(bugprone-macro-parentheses)
#define IOX_BUILDER_SWITCH(name) \
public: \
auto name()&& noexcept -> decltype(auto) { \
m_##name = true; \
return std::move(*this); \
} \
\
private: \
bool m_##name { false };

#define IOX_BUILDER_PARAMETER(type, name, defaultValue) \
public: \
auto name(type const& value)&& noexcept -> decltype(auto) { \
Expand Down
12 changes: 12 additions & 0 deletions iceoryx2-ffi/cxx/include/iox2/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,18 @@ class Event {
auto event_id_max_value() && -> size_t;
/// Set the largest event id supported by the event service
void set_event_id_max_value(size_t value) &&;
/// Defines the event id value that is emitted after a new notifier was created.
auto notifier_created_event() && -> iox::optional<size_t>;
/// Sets the event id value that is emitted after a new notifier was created.
void set_notifier_created_event(iox::optional<size_t> value) &&;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this intentional to deviate from the Rust API or just an overlook?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is intentional. In the builder it is no longer an optional but for the global config and the config file it is an optional. Some = emit event, None = no event.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it make sense to have the same API with disable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. In Rust the config is a struct where all members are public and can be set by the user directly. It is also serializable and stored in the iceoryx2.toml file. This config entry is still an Option<EventId> and it does not make sense to split it up into two fields since then we confuse the user and may have entries that are in contradiction to each other.

We require here a C++ API since we cannot access the struct members directly in C++. But the API shall reflect the underlying structure of the Rust structs/members. Therefore this method has still an optional.

/// Defines the event id value that is emitted before a new notifier is dropped.
auto notifier_dropped_event() && -> iox::optional<size_t>;
/// Sets the event id value that is emitted before a new notifier is dropped.
void set_notifier_dropped_event(iox::optional<size_t> value) &&;
/// Defines the event id value that is emitted if a notifier was identified as dead.
auto notifier_dead_event() && -> iox::optional<size_t>;
/// Sets the event id value that is emitted if a notifier was identified as dead.
void set_notifier_dead_event(iox::optional<size_t> value) &&;

private:
friend class Defaults;
Expand Down
6 changes: 6 additions & 0 deletions iceoryx2-ffi/cxx/include/iox2/event_id.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ class EventId {
};

auto operator<<(std::ostream& stream, const EventId& value) -> std::ostream&;
auto operator==(const EventId& lhs, const EventId& rhs) -> bool;
auto operator!=(const EventId& lhs, const EventId& rhs) -> bool;
auto operator<(const EventId& lhs, const EventId& rhs) -> bool;
auto operator<=(const EventId& lhs, const EventId& rhs) -> bool;
auto operator>(const EventId& lhs, const EventId& rhs) -> bool;
auto operator>=(const EventId& lhs, const EventId& rhs) -> bool;
} // namespace iox2

#endif
33 changes: 33 additions & 0 deletions iceoryx2-ffi/cxx/include/iox2/service_builder_event.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "iox/expected.hpp"
#include "iox2/attribute_specifier.hpp"
#include "iox2/attribute_verifier.hpp"
#include "iox2/event_id.hpp"
#include "iox2/internal/iceoryx2.hpp"
#include "iox2/port_factory_event.hpp"
#include "iox2/service_builder_event_error.hpp"
Expand Down Expand Up @@ -49,6 +50,31 @@ class ServiceBuilderEvent {
IOX_BUILDER_OPTIONAL(uint64_t, max_listeners);

public:
/// If the [`Service`] is created it defines the event that shall be emitted by every
/// [`Notifier`] before it is dropped. If [`None`] is
/// provided a [`Notifier`] will not emit an event.
auto notifier_dropped_event(EventId event_id) && -> ServiceBuilderEvent&&;

/// If the [`Service`] is created it defines the event that shall be emitted by every newly
/// created [`Notifier`].
auto notifier_created_event(EventId event_id) && -> ServiceBuilderEvent&&;

/// If the [`Service`] is created it defines the event that shall be emitted when a
/// [`Notifier`] is identified as dead. If [`None`] is
/// provided no event will be emitted.
auto notifier_dead_event(EventId event_id) && -> ServiceBuilderEvent&&;

/// If the [`Service`] is created it disables sending an event when a notifier was dropped.
auto disable_notifier_dropped_event() && -> ServiceBuilderEvent&&;

/// If the [`Service`] is created it disables sending an event when a new notifier was created.
auto disable_notifier_created_event() && -> ServiceBuilderEvent&&;

/// If the [`Service`] is created it disables sending an event when a notifier was identified
/// as dead.
auto disable_notifier_dead_event() && -> ServiceBuilderEvent&&;


/// If the [`Service`] exists, it will be opened otherwise a new [`Service`] will be
/// created.
auto open_or_create() && -> iox::expected<PortFactoryEvent<S>, EventOpenOrCreateError>;
Expand Down Expand Up @@ -84,6 +110,13 @@ class ServiceBuilderEvent {
void set_parameters();

iox2_service_builder_event_h m_handle = nullptr;

iox::optional<EventId> m_notifier_dead_event;
iox::optional<EventId> m_notifier_created_event;
iox::optional<EventId> m_notifier_dropped_event;
bool m_verify_notifier_dead_event = false;
bool m_verify_notifier_created_event = false;
bool m_verify_notifier_dropped_event = false;
};
} // namespace iox2

Expand Down
11 changes: 11 additions & 0 deletions iceoryx2-ffi/cxx/include/iox2/static_config_event.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#ifndef IOX2_STATIC_CONFIG_EVENT_HPP
#define IOX2_STATIC_CONFIG_EVENT_HPP

#include "iox/optional.hpp"
#include "iox2/event_id.hpp"
#include "iox2/iceoryx2.h"
#include "iox2/internal/iceoryx2.hpp"

Expand All @@ -35,6 +37,15 @@ class StaticConfigEvent {
/// Returns the largest [`EventId`] that is supported by the service
auto event_id_max_value() const -> size_t;

/// Returns the emitted [`EventId`] when a new notifier is created.
auto notifier_created_event() const -> iox::optional<EventId>;

/// Returns the emitted [`EventId`] when a notifier is dropped.
auto notifier_dropped_event() const -> iox::optional<EventId>;

/// Returns the emitted [`EventId`] when a notifier is identified as dead.
auto notifier_dead_event() const -> iox::optional<EventId>;

private:
template <ServiceType>
friend class PortFactoryEvent;
Expand Down
52 changes: 52 additions & 0 deletions iceoryx2-ffi/cxx/src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,58 @@ auto Event::event_id_max_value() && -> size_t {
void Event::set_event_id_max_value(size_t value) && {
iox2_config_defaults_event_set_event_id_max_value(m_config, value);
}

auto Event::notifier_created_event() && -> iox::optional<size_t> {
size_t value = 0;
if (iox2_config_defaults_event_notifier_created_event(m_config, &value)) {
return { value };
}

return iox::nullopt;
}

void Event::set_notifier_created_event(iox::optional<size_t> value) && {
if (value.has_value()) {
iox2_config_defaults_event_set_notifier_created_event(m_config, &*value);
} else {
iox2_config_defaults_event_set_notifier_created_event(m_config, nullptr);
}
}

auto Event::notifier_dropped_event() && -> iox::optional<size_t> {
size_t value = 0;
if (iox2_config_defaults_event_notifier_dropped_event(m_config, &value)) {
return { value };
}

return iox::nullopt;
}

void Event::set_notifier_dropped_event(iox::optional<size_t> value) && {
if (value.has_value()) {
iox2_config_defaults_event_set_notifier_dropped_event(m_config, &*value);
} else {
iox2_config_defaults_event_set_notifier_dropped_event(m_config, nullptr);
}
}

auto Event::notifier_dead_event() && -> iox::optional<size_t> {
size_t value = 0;
if (iox2_config_defaults_event_notifier_dead_event(m_config, &value)) {
return { value };
}

return iox::nullopt;
}

void Event::set_notifier_dead_event(iox::optional<size_t> value) && {
if (value.has_value()) {
iox2_config_defaults_event_set_notifier_dead_event(m_config, &*value);
} else {
iox2_config_defaults_event_set_notifier_dead_event(m_config, nullptr);
}
}

/////////////////////////
// END: Event
/////////////////////////
Expand Down
25 changes: 24 additions & 1 deletion iceoryx2-ffi/cxx/src/event_id.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
// SPDX-License-Identifier: Apache-2.0 OR MIT

#include "iox2/event_id.hpp"
#include "iox/assertions_addendum.hpp"

namespace iox2 {
EventId::EventId(const size_t value)
Expand All @@ -30,4 +29,28 @@ auto operator<<(std::ostream& stream, const EventId& value) -> std::ostream& {
stream << "EventId { m_value: " << value.as_value() << " }";
return stream;
}

auto operator==(const EventId& lhs, const EventId& rhs) -> bool {
return lhs.as_value() == rhs.as_value();
}

auto operator!=(const EventId& lhs, const EventId& rhs) -> bool {
return lhs.as_value() != rhs.as_value();
}

auto operator<(const EventId& lhs, const EventId& rhs) -> bool {
return lhs.as_value() < rhs.as_value();
}

auto operator<=(const EventId& lhs, const EventId& rhs) -> bool {
return lhs.as_value() <= rhs.as_value();
}

auto operator>(const EventId& lhs, const EventId& rhs) -> bool {
return lhs.as_value() > rhs.as_value();
}

auto operator>=(const EventId& lhs, const EventId& rhs) -> bool {
return lhs.as_value() >= rhs.as_value();
}
} // namespace iox2
64 changes: 64 additions & 0 deletions iceoryx2-ffi/cxx/src/service_builder_event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,74 @@ template <ServiceType S>
void ServiceBuilderEvent<S>::set_parameters() {
m_max_notifiers.and_then([&](auto value) { iox2_service_builder_event_set_max_notifiers(&m_handle, value); });
m_max_listeners.and_then([&](auto value) { iox2_service_builder_event_set_max_listeners(&m_handle, value); });

if (m_verify_notifier_created_event) {
m_notifier_created_event
.and_then(
[&](auto value) { iox2_service_builder_event_set_notifier_created_event(&m_handle, value.as_value()); })
.or_else([&]() { iox2_service_builder_event_disable_notifier_created_event(&m_handle); });
}

if (m_verify_notifier_dropped_event) {
m_notifier_dropped_event
.and_then(
[&](auto value) { iox2_service_builder_event_set_notifier_dropped_event(&m_handle, value.as_value()); })
.or_else([&]() { iox2_service_builder_event_disable_notifier_dropped_event(&m_handle); });
}

if (m_verify_notifier_dead_event) {
m_notifier_dead_event
.and_then(
[&](auto value) { iox2_service_builder_event_set_notifier_dead_event(&m_handle, value.as_value()); })
.or_else([&]() { iox2_service_builder_event_disable_notifier_dead_event(&m_handle); });
}

m_max_nodes.and_then([](auto) { IOX_TODO(); });
m_event_id_max_value.and_then([](auto) { IOX_TODO(); });
}

template <ServiceType S>
auto ServiceBuilderEvent<S>::notifier_dropped_event(EventId event_id) && -> ServiceBuilderEvent&& {
m_notifier_dropped_event.emplace(event_id);
m_verify_notifier_dropped_event = true;
return std::move(*this);
}

template <ServiceType S>
auto ServiceBuilderEvent<S>::notifier_created_event(EventId event_id) && -> ServiceBuilderEvent&& {
m_notifier_created_event.emplace(event_id);
m_verify_notifier_created_event = true;
return std::move(*this);
}

template <ServiceType S>
auto ServiceBuilderEvent<S>::notifier_dead_event(EventId event_id) && -> ServiceBuilderEvent&& {
m_notifier_dead_event.emplace(event_id);
m_verify_notifier_dead_event = true;
return std::move(*this);
}

template <ServiceType S>
auto ServiceBuilderEvent<S>::disable_notifier_dropped_event() && -> ServiceBuilderEvent&& {
m_notifier_dropped_event.reset();
m_verify_notifier_dropped_event = true;
return std::move(*this);
}

template <ServiceType S>
auto ServiceBuilderEvent<S>::disable_notifier_created_event() && -> ServiceBuilderEvent&& {
m_notifier_created_event.reset();
m_verify_notifier_created_event = true;
return std::move(*this);
}

template <ServiceType S>
auto ServiceBuilderEvent<S>::disable_notifier_dead_event() && -> ServiceBuilderEvent&& {
m_notifier_dead_event.reset();
m_verify_notifier_dead_event = true;
return std::move(*this);
}

template <ServiceType S>
auto ServiceBuilderEvent<S>::open_or_create() && -> iox::expected<PortFactoryEvent<S>, EventOpenOrCreateError> {
set_parameters();
Expand Down
27 changes: 27 additions & 0 deletions iceoryx2-ffi/cxx/src/static_config_event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,40 @@ StaticConfigEvent::StaticConfigEvent(iox2_static_config_event_t value)
auto StaticConfigEvent::max_nodes() const -> size_t {
return m_value.max_nodes;
}

auto StaticConfigEvent::max_notifiers() const -> size_t {
return m_value.max_notifiers;
}

auto StaticConfigEvent::max_listeners() const -> size_t {
return m_value.max_listeners;
}

auto StaticConfigEvent::event_id_max_value() const -> size_t {
return m_value.event_id_max_value;
}

auto StaticConfigEvent::notifier_created_event() const -> iox::optional<EventId> {
if (!m_value.has_notifier_created_event) {
return iox::nullopt;
}

return { EventId(m_value.notifier_created_event) };
}

auto StaticConfigEvent::notifier_dropped_event() const -> iox::optional<EventId> {
if (!m_value.has_notifier_dropped_event) {
return iox::nullopt;
}

return { EventId(m_value.notifier_dropped_event) };
}

auto StaticConfigEvent::notifier_dead_event() const -> iox::optional<EventId> {
if (!m_value.has_notifier_dead_event) {
return iox::nullopt;
}

return { EventId(m_value.notifier_dead_event) };
}
} // namespace iox2
Loading
Loading