Skip to content

Commit

Permalink
[#555] Add cxx readme
Browse files Browse the repository at this point in the history
  • Loading branch information
elfenpiff committed Dec 19, 2024
1 parent 2dda328 commit 0e23095
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 1 deletion.
2 changes: 1 addition & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ These types are demonstrated in the complex data types example.
| event | [C](c/event) [C++](cxx/event) [Rust](rust/event) | Push notifications - send event signals to wakeup processes that are waiting for them. |
| event based communication | [C++](cxx/event_based_communication) [Rust](rust/event_based_communication) | Define multiple events like publisher/subscriber created or removed, send sample, received sample, deliver history etc. and react on them for a fully event driven communication setup. |
| event multiplexing | [C](c/event_multiplexing) [C++](cxx/event_multiplexing) [Rust](rust/event_multiplexing) | Wait on multiple listeners or sockets with a single call. The WaitSet demultiplexes incoming events and notifies the user. |
| health monitoring | [Rust](rust/health_monitoring) | A central daemon creates the communication resources and monitors all nodes. When the central daemon crashes other nodes can take over and use the decentral API to monitor the nodes. |
| health monitoring | [C++](cxx/health_monitoring) [Rust](rust/health_monitoring) | A central daemon creates the communication resources and monitors all nodes. When the central daemon crashes other nodes can take over and use the decentral API to monitor the nodes. |
| publish subscribe | [C](c/publish_subscribe) [C++](cxx/publish_subscribe) [Rust](rust/publish_subscribe) | Communication between multiple processes with a [publish subscribe messaging pattern](https://en.wikipedia.org/wiki/Publish–subscribe_pattern). |
| publish subscribe dynamic data | [C++](cxx/publish_subscribe_dynamic_data) [Rust](rust/publish_subscribe_dynamic_data) | Communication between multiple processes with a [publish subscribe messaging pattern](https://en.wikipedia.org/wiki/Publish–subscribe_pattern) and payload data that has a dynamic size. |
| publish subscribe with user header | [C](c/publish_subscribe_with_user_header) [C++](cxx/publish_subscribe_with_user_header) [Rust](rust/publish_subscribe_with_user_header) | Add a user header to the payload (samples) to transfer additional information. |
Expand Down
139 changes: 139 additions & 0 deletions examples/cxx/health_monitoring/README.md
Original file line number Diff line number Diff line change
@@ -1 +1,140 @@
# Health Monitoring

Before proceeding, all dependencies need to be installed. You can find
instructions in the [C++ Examples Readme](../README.md).

This example demonstrates how to create a robust system using iceoryx2.
A central daemon pre-creates all communication resources to ensure that every
required resource, such as memory, is available as soon as the application
starts.
Additionally, the subscriber is immediately informed if one of the processes
it depends on has crashed. Even if the central daemon itself crashes,
communication can continue without any restrictions. Thanks to the
decentralized API of iceoryx2, the subscriber can take over the role of the
central daemon and continue monitoring all processes.

The communication must also be reliable, and we expect publishers to provide
updates at regular intervals. If a publisher misses a deadline, we want to be
informed immediately. This situation can occur if the system is under heavy
load or if a process has crashed.

This example is more advanced and consists of four components:

* `central_daemon` - Must run first. It creates all communication resources and
monitors all nodes/processes.
* `publisher_1` - Sends data at a specific frequency on `service_1`.
* `publisher_2` - Sends data at a specific frequency on `service_2`.
* `subscriber` - Connects to `service_1` and `service_2` and expects new samples
within a specific time. If no sample arrives, it proactively checks for dead
nodes.

```ascii
+----------------+ creates ...........................
| central_daemon | ----------> : communication resources :
+----------------+ ...........................
| ^
| opens |
| +-----------------+--------------+
| | | |
| +-------------+ +-------------+ +------------+
| | publisher_1 | | publisher_2 | | subscriber |
| +-------------+ +-------------+ +------------+
| ^ ^ ^
| monitores | | |
+-------------+-------------------+-----------------+
```

## Running The Example

> [!CAUTION]
> Every payload you transmit with iceoryx2 must be compatible with shared
> memory. Specifically, it must:
>
> * be self contained, no heap, no pointers to external sources
> * have a uniform memory representation -> `#[repr(C)]`
> * not use pointers to manage their internal structure
>
> Data types like `String` or `Vec` will cause undefined behavior and may
> result in segmentation faults. We provide alternative data types that are
> compatible with shared memory. See the
> [complex data type example](../complex_data_types) for guidance on how to
> use them.
First you have to build the C++ examples:

```sh
cmake -S . -B target/ffi/build -DBUILD_EXAMPLES=ON
cmake --build target/ffi/build
```

For this example, you need to open five separate terminals.

## Terminal 1: Central Daemon - Create All Communication Resources

Run the central daemon, which sets up all communication resources and monitors
processes.

```sh
./target/ffi/build/examples/cxx/health_monitoring/example_cxx_health_monitoring_central_daemon
```

## Terminal 2: Publisher 1

Run the first publisher, which sends data on `service_1`.

```sh
./target/ffi/build/examples/cxx/health_monitoring/example_cxx_health_monitoring_publisher_1
```

## Terminal 3: Publisher 2

Run the second publisher, which sends data on `service_2`.

```sh
./target/ffi/build/examples/cxx/health_monitoring/example_cxx_health_monitoring_publisher_2
```

## Terminal 4: Subscriber

Run the subscriber, which listens to both `service_1` and `service_2`.

```sh
./target/ffi/build/examples/cxx/health_monitoring/example_cxx_health_monitoring_subscriber
```

## Terminal 5: Simulate Process Crashes

Send a `SIGKILL` signal to `publisher_1` to simulate a fatal crash. This
ensures that the process is unable to clean up any resources.

```sh
killall -9 example_cxx_health_monitoring_publisher_1
```

After running this command:

1. The `central_daemon` will detect that the process has crashed and print:
```ascii
detected dead node: Some(NodeName { value: "publisher 1" })
```
The event service is configured to emit a `PubSub::ProcessDied` event when a
process is identified as dead.

2. On the `subscriber` side, you will see the message:
```ascii
ServiceName { value: "service_1" }: process died!
```

3. Since `publisher_1` is no longer sending messages, the subscriber will also
regularly print another message indicating that `service_1` has violated
the contract because no new samples are being received.

Feel free to run multiple instances of publisher or subscriber processes
simultaneously to explore how iceoryx2 handles publisher-subscriber
communication efficiently.

You may hit the maximum supported number of ports when too many publisher or
subscriber processes run. Take a look at the [iceoryx2 config](../../../config)
to set the limits globally or at the
[API of the Service builder](https://docs.rs/iceoryx2/latest/iceoryx2/service/index.html)
to set them for a single service.
10 changes: 10 additions & 0 deletions examples/rust/health_monitoring/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,13 @@ After running this command:
3. Since `publisher_1` is no longer sending messages, the subscriber will also
regularly print another message indicating that `service_1` has violated
the contract because no new samples are being received.

Feel free to run multiple instances of publisher or subscriber processes
simultaneously to explore how iceoryx2 handles publisher-subscriber
communication efficiently.

You may hit the maximum supported number of ports when too many publisher or
subscriber processes run. Take a look at the [iceoryx2 config](../../../config)
to set the limits globally or at the
[API of the Service builder](https://docs.rs/iceoryx2/latest/iceoryx2/service/index.html)
to set them for a single service.

0 comments on commit 0e23095

Please sign in to comment.