Skip to content

Commit

Permalink
iox-eclipse-iceoryx#482 clearer distinction between graceful/abnormal…
Browse files Browse the repository at this point in the history
… termination, use

single ` for inline code blocks

Signed-off-by: Marika Lehmann <marika.lehmann@apex.ai>
  • Loading branch information
FerdinandSpitzschnueffler authored and marthtz committed May 12, 2021
1 parent 6cef1b4 commit 2b51166
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
Many parts of the iceoryx C++ API follow a functional programming approach and allow the user to specify functions
which handle the possible cases, e.g. what should happen when data is received.

This is very flexible but requires using the monadic types ``cxx::expected`` and ``cxx::optional``, which we
This is very flexible but requires using the monadic types `cxx::expected` and `cxx::optional`, which we
introduce in the following sections.

## Optional

The type ``iox::cxx::optional<T>`` is used to indicate that there may or may not be a value of a specific type ``T``
The type `iox::cxx::optional<T>` is used to indicate that there may or may not be a value of a specific type `T`
available. This is essentially the 'maybe [monad](https://en.wikipedia.org/wiki/Monad_(functional_programming))' in
functional programming. Assuming we have some optional (usually the result of some computation)

Expand Down Expand Up @@ -56,31 +56,31 @@ optional<int> result = 73;
result = 37;
```

If the optional is default initialized, it is automatically set to its null value of type ``iox::cxx::nullopt_t``.
This can be also done directly by using the constant ``iox::cxx::nullopt``
If the optional is default initialized, it is automatically set to its null value of type `iox::cxx::nullopt_t`.
This can be also done directly by using the constant `iox::cxx::nullopt`

```cpp
result = iox::cxx::nullopt;
```

For a complete list of available functions see
[``optional.hpp``](https://github.com/eclipse-iceoryx/iceoryx/blob/master/iceoryx_utils/include/iceoryx_utils/cxx/optional.hpp).
The ``iox::cxx::optional`` behaves like the [``std::optional``](https://en.cppreference.com/w/cpp/utility/optional)
[`optional.hpp`](https://github.com/eclipse-iceoryx/iceoryx/blob/master/iceoryx_utils/include/iceoryx_utils/cxx/optional.hpp).
The `iox::cxx::optional` behaves like the [`std::optional`](https://en.cppreference.com/w/cpp/utility/optional)
except that it does not throw exceptions and has no undefined behavior.

## Expected

``iox::cxx::expected<T, E>`` generalizes ``iox::cxx::optional`` by admitting a value of another type ``E`` instead of
no value at all, i.e. it contains either a value of type ``T`` or ``E``. In this way, ``expected`` is a special case of
the 'either monad'. It is usually used to pass a value of type ``T`` or an error that may have occurred, i.e. ``E`` is the
error type. ``E`` must contain a static member or an enum value called ``INVALID_STATE``. Alternatively an
[``ErrorTypeAdapter``](https://github.com/eclipse-iceoryx/iceoryx/blob/5b1a0514e72514c2eae8a9d071d82a3905fedf8b/iceoryx_utils/include/iceoryx_utils/cxx/expected.hpp#L46)
`iox::cxx::expected<T, E>` generalizes `iox::cxx::optional` by admitting a value of another type `E` instead of
no value at all, i.e. it contains either a value of type `T` or `E`. In this way, `expected` is a special case of
the 'either monad'. It is usually used to pass a value of type `T` or an error that may have occurred, i.e. `E` is the
error type. `E` must contain a static member or an enum value called `INVALID_STATE`. Alternatively an
[`ErrorTypeAdapter`](https://github.com/eclipse-iceoryx/iceoryx/blob/5b1a0514e72514c2eae8a9d071d82a3905fedf8b/iceoryx_utils/include/iceoryx_utils/cxx/expected.hpp#L46)
can be implemented.

For more information on how it is used for error handling see
[error-handling.md](https://github.com/eclipse-iceoryx/iceoryx/blob/master/doc/design/error-handling.md).

Assume we have ``E`` as an error type, then we can create a value
Assume we have `E` as an error type, then we can create a value

```cpp
iox::cxx::expected<int, E> result(iox::cxx::success<int>(73));
Expand All @@ -107,7 +107,7 @@ If we need an error value, we set
result = iox::cxx::error<E>(errorCode);
```

which assumes that ``E`` can be constructed from an ``errorCode``.
which assumes that `E` can be constructed from an `errorCode`.

We again can employ a functional approach like this:

Expand All @@ -117,11 +117,11 @@ auto handleError = [](E& value) { /*handle the error*/ };
result.and_then(handleValue).or_else(handleError);
```
There are more convenience functions such as ``value_or`` which provides the value or an alternative specified by the
There are more convenience functions such as `value_or` which provides the value or an alternative specified by the
user. These can be found in
[``expected.hpp``](https://github.com/eclipse-iceoryx/iceoryx/blob/master/iceoryx_utils/include/iceoryx_utils/cxx/expected.hpp).
[`expected.hpp`](https://github.com/eclipse-iceoryx/iceoryx/blob/master/iceoryx_utils/include/iceoryx_utils/cxx/expected.hpp).
Note that when we move an ``expected``, the origin is set to the error value ``E::INVALID_STATE`` and ``has_error()`` will
Note that when we move an `expected`, the origin is set to the error value `E::INVALID_STATE` and `has_error()` will
always return true:
```cpp
Expand Down
41 changes: 20 additions & 21 deletions doc/website/getting-started/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ set up iceoryx applications.
To set up a collection of applications using iceoryx (an _iceoryx system_), the applications need to initialize a
runtime and create _publishers_ and _subscribers_. The publishers send data of a specific _topic_ which can be
received by subscribers of the same topic. To enable publishers to offer their topic and subscribers to subscribe to
these offered topics, the middleware daemon, called ``RouDi``, must be running.
these offered topics, the middleware daemon, called `RouDi`, must be running.

But before we get into more details, let's start with a simple example.

Expand Down Expand Up @@ -52,10 +52,10 @@ else
}
```

Here ``result`` is an ``expected`` and hence we may get an error. This can happen if we try to loan too many samples
and exhaust memory. We have to handle this potential error since the expected class has the ``nodiscard`` keyword
Here `result` is an `expected` and hence we may get an error. This can happen if we try to loan too many samples
and exhaust memory. We have to handle this potential error since the expected class has the `nodiscard` keyword
attached. This means we get a warning (or an error when build in strict mode) when we don't handle it. We could also
explicitly discard it with ``IOX_DISCARD_RESULT`` which is discouraged. If you want to know more about ``expected``,
explicitly discard it with `IOX_DISCARD_RESULT` which is discouraged. If you want to know more about `expected`,
take a look at
[How optional and error values are returned in iceoryx](../advanced/how-optional-and-error-values-are-returned-in-iceoryx.md).

Expand Down Expand Up @@ -92,7 +92,7 @@ while (keepRunning)
}
```

By calling ``take`` we get an ``expected`` and hence we have to handle the potential error.
By calling `take` we get an `expected` and hence we have to handle the potential error.

And that's it. We have created our first simple iceoryx example.
[Here](https://github.com/eclipse-iceoryx/iceoryx/blob/master/iceoryx_examples/README.md) you can find further examples
Expand Down Expand Up @@ -130,8 +130,7 @@ applications use for exchanging payload data. Sometimes referred to as daemon, R
responsible for the service discovery, i.e. enabling subscribers to find topics offered by publishers. It also keeps
track of all applications which have initialized a runtime and are hence able to use publishers or subscribers.

When an application terminates, RouDi cleans up all resources needed for the communication with RouDi. If an
application crashes, it also takes care about the clean-up. Due to our mostly lock-free inter-process mechanisms
When an application crashes, RouDi cleans up all resources. Due to our mostly lock-free inter-process mechanisms
(only one last lock; we are working to remove it), iceoryx-based communication is much more reliable compared to
traditional mechanism using locking.

Expand Down Expand Up @@ -167,20 +166,20 @@ application's address space.
### Creating service descriptions for topics
A ``ServiceDescription`` in iceoryx represents a topic under which publisher and subscribers can exchange data and is
A `ServiceDescription` in iceoryx represents a topic under which publisher and subscribers can exchange data and is
uniquely identified by three string identifiers.
1. ``Group`` name
2. ``Instance`` name
3. ``Topic`` name
1. `Group` name
2. `Instance` name
3. `Topic` name
A triple consisting of such strings is called a ``ServiceDescription``. Two ``ServiceDescription``s are considered
A triple consisting of such strings is called a `ServiceDescription`. Two `ServiceDescription`s are considered
matching if all these three strings are element-wise equal, i.e. group, instance and topic names are the same for both
of them. This means the group and instance identifier can be ignored to create different ``ServiceDescription``s. They
of them. This means the group and instance identifier can be ignored to create different `ServiceDescription`s. They
will be needed for advanced filtering functionality in the future.
The service model of iceoryx is derived from AUTOSAR and is still used in the API with these names (``Service``,
``Instance``, ``Event``). The so called canonical protocol is implemented in the namespace ``capro``.
The service model of iceoryx is derived from AUTOSAR and is still used in the API with these names (`Service`,
`Instance`, `Event`). The so called canonical protocol is implemented in the namespace `capro`.
The following table gives an overview of the different terminologies and the current mapping:
Expand All @@ -207,8 +206,8 @@ MyRadarService frontLeftRadarInstance;
std::cout << frontLeftRadarInstance.hasObstacleDetected << std::endl;
```

In the iceoryx world we would subscribe to the service ``("MyRadarService", "frontLeftRadarInstance", "hasObstacleDetected")``
and would receive a sample whenever an obstacle was detected. Or we would subscribe to ``distanceToObstacle`` and would
In the iceoryx world we would subscribe to the service `("MyRadarService", "frontLeftRadarInstance", "hasObstacleDetected")`
and would receive a sample whenever an obstacle was detected. Or we would subscribe to `distanceToObstacle` and would
receive a constant stream of data which presents the distance to the obstacle.

#### Restrictions
Expand Down Expand Up @@ -253,8 +252,8 @@ indeterminate order between different publishers).

The easiest way to receive data is to periodically poll whether data is available. This is sufficient for simple use
cases but inefficient in general, as it often leads to unnecessary latency and wake-ups without data. An alternative
approach to receive data is to wait for user-defined events to occur. This is provided by our ``WaitSet`` and
``Listener`` which are introduced in the following sections.
approach to receive data is to wait for user-defined events to occur. This is provided by our `WaitSet` and
`Listener` which are introduced in the following sections.

### WaitSet

Expand Down Expand Up @@ -298,10 +297,10 @@ The API is offered in two languages, C++ and C. Detailed information can be foun
[C example](../examples/icedelivery_in_c/).

Many parts of the C++ API follow a functional programming approach which is less error-prone. This requires using
the monadic types ``cxx::expected`` and ``cxx::optional`` which are introduced
the monadic types `cxx::expected` and `cxx::optional` which are introduced
[here](../advanced/how-optional-and-error-values-are-returned-in-iceoryx.md).

With the C++ API, we distinguish between the ``typed API`` and the ``untyped API``. In the typed API, the underlying
With the C++ API, we distinguish between the `typed API` and the `untyped API`. In the typed API, the underlying
data type is made apparent by typed pointers or references to some data type T (often a template parameter). This allows
working with the data in a C++ idiomatic and type-safe way and should be preferred whenever possible. The typed API is
mainly used when iceoryx is used stand-alone, i.e. not integrated into a third party framework.
Expand Down

0 comments on commit 2b51166

Please sign in to comment.