From b9750e659d73e52da8fc8b7a1c93f25b50809870 Mon Sep 17 00:00:00 2001 From: William Lyles <26171886+wilyle@users.noreply.github.com> Date: Wed, 24 Jan 2024 16:05:09 -0800 Subject: [PATCH] self-review --- docs/design/README.md | 16 ++++++++-------- docs/tutorials/custom-adapters.md | 4 ++-- docs/tutorials/quickstart.md | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 2c1bbcd..9db291a 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -28,7 +28,7 @@ The following is a more detailed diagram illustrating how the components interac The cartographer is the core component responsible for managing the entity map and tracking which signals should be synchronized to the cloud. -The cartographer interfaces with the mapping adapter to poll the mapping service for updates. If there is an update pending, the cartographer will download it and interface with the digital twin adapter to look up the corresponding entity information. Then, the cartographer will use this information to register data adapters with the data adapter selector. Finally, the cartographer will populate the signal store with the signals that should be tracked. If any part of this process fails for a given entity, the cartographer will retry again at a later time. +The cartographer interfaces with the mapping adapter to poll the mapping service for updates. If there is an update pending, the cartographer will download it and interface with the digital twin adapter to look up the corresponding entity information. Then, the cartographer will use this information to register data adapters with the data adapter selector. Finally, the cartographer will populate the signal store with the signals that should be tracked. If any part of this process fails for a given entity, the signal will not be tracked and the cartographer will retry again at a later time. The following diagram illustrates the communication between the cartographer and the mapping service: @@ -38,15 +38,15 @@ The following diagram illustrates the communication between the cartographer and The emitter is the core component responsible for actually emitting data. The emitter interfaces with the signal store to determine which signals should be emitted. Every signal present in the store will be emitted according to its mapping configuration. -The emitter supports intervals at a per-signal level to enable signals to have different requirements on how often they are synced with the cloud. Note that once a signal is added to the mapping and picked up by the cartographer, it can take up to `min(`*`I`*`)` before the signal is emitted, where *`I`* is the set of intervals for signals already being tracked. +The emitter supports intervals at a per-signal level to enable signals to have different requirements on how often they are synced with the cloud. Note that once a signal is added to the mapping and picked up by the cartographer, there can de a delay of up to `min(`*`I`*`)` before the signal is emitted, where *`I`* is the set of intervals for signals already being tracked. ### Data Adapter Selector The data adapter selector is the core component responsible for managing communication with data adapters. It behaves like a gateway service and allows callers to interact with the correct data adapter for a given entity. -The data adapter selector's main interface is the `create_or_update_adapter` function, which accepts an entity description as an argument. When calling this function, the data adapter selector will first use the entity's endpoint URI to search for an existing adapter that can handle the requested entity. If no such adapter is found, the entity's protocol and operation are used to search for an adapter type that can handle that entity, and then an adapter is created. In either case, the new entity is registered with the adapter, which then interfaces with that entity's endpoint to obtain data. +The data adapter selector's main interface is the `create_or_update_adapter` function, which accepts an entity description as an argument. When calling this function, the data adapter selector will first use the entity's endpoint information to search for an existing adapter that can handle the requested entity. If no such adapter is found, the entity's protocol and operation are used to search for an adapter type that can handle that entity, and then an adapter is created. In either case, the new entity is registered with the adapter, which then interfaces with that entity's endpoint to obtain data. -The data adapter selector also supports a "loopback" functionality. When registering an entity with an adapter, the adapter may return a request for a loopback with updated entity info. This indicates to the selector that the matched adapter cannot handle the originally requested entity, but has modified its contents to redirect it to another adapter. This enables scenarios such as managed subscribe to perform pre-processing on entities and recycle other existing data adapters. For more information on the managed subscribe functionality, see the [Eclipse Agemo project](https://github.com/eclipse-chariott/agemo). +The data adapter selector also supports "loopback" functionality. When registering an entity with an adapter, the adapter may return a request for a loopback with updated entity info. This indicates to the selector that the matched adapter cannot handle the originally requested entity directly, but has modified its contents to redirect it to another adapter. This enables scenarios such as managed subscribe to perform pre-processing on entities while recycling other data adapter implementations which are independent of managed subscriptions. For more information on the managed subscribe functionality, see the [Eclipse Agemo project](https://github.com/eclipse-chariott/agemo). Below is a sequence diagram illustrating the data adapter selection process: @@ -54,9 +54,9 @@ Below is a sequence diagram illustrating the data adapter selection process: ### Signal Store -The signal store is the core component responsible for managing signal values. The signal store is considered the source of truth for which signals should be emitted, how they should be emitted, and what the most up-to-date value is for each signal. Each other core component interfaces with the signal store in some way to track, read, and write signal values. +The signal store is the core component responsible for managing signal values. The signal store is considered to be the source of truth for which signals should be emitted, how they should be emitted, and what the most up-to-date value is for each signal. Each other core component interfaces with the signal store in some way to track, read, and write signal values. -Note that the signal store is not intended to be a complete mirror of the vehicle signal state, but rather tracks only the signals of interest to Freyja's other core components. +Note that the signal store is not intended to be a complete mirror of the vehicle signal state, but rather tracks only the signals of interest to Freyja. ### External Interfaces @@ -87,8 +87,8 @@ The data adapters interface with providers to retrieve data from entities, such The `DataAdapter` interface requires the following function implementations: - `create_new`: Serves as an integration point. This is typically used by the corresponding `DataAdapterFactory` implementation of `create_adapter` (see below). -- `start`: Starts the data adapter. This function should be non-blocking. Any required servers, listeners, and so on should be initialized as a separate thread or task. -- `send_request_to_provider`: Sends a request to a provider to publish data immediately. In most use cases data is updated asynchronously with a subscription model, but this function allows for a more traditional synchronous-like interface. Note that the adapter is still expected to update data asynchronously, as the return type of the function does not contain any data. +- `start`: Starts the data adapter. This function should not block indefinitely. Any required servers, listeners, and so on should be initialized as a separate thread or task. +- `send_request_to_provider`: Sends a request to a provider to publish data immediately. In most use cases data is updated asynchronously with a publisher-subscriber model, but this function allows for a more traditional synchronous-like interface. Note that the adapter is still expected to update data in the signal store asynchronously, as the return type of the function does not contain any data. - `register_entity`: Registers an entity with this adapter. The `DataAdapterFactory` interface requires the following function implementations: diff --git a/docs/tutorials/custom-adapters.md b/docs/tutorials/custom-adapters.md index 34edb68..2b01e82 100644 --- a/docs/tutorials/custom-adapters.md +++ b/docs/tutorials/custom-adapters.md @@ -1,12 +1,12 @@ # Writing Custom Adapters and Integrating with Freyja -Freyja allows users to bring their own implementations of various traits which interface with external components. This is achieved by exposing the core functionality of Freyja as a library function and requiring users to author the final binary package to link everything together. In most cases authoring the final executable can be simplified by using a provided macro, but for scenarios that require more complex setup for the adapters the library function can be called manually. +Freyja allows users to bring their own implementations of various traits which interface with external components. This is achieved by exposing the core functionality of Freyja as a library function and requiring users to author the final binary package to link everything together. For more examples of Freyja adapters and applications, see the [Ibeji Example Applications repository](https://github.com/eclipse-ibeji/ibeji-example-applications). ## How to Author a Custom Adapter -Freyja supports custom implementations of the `DigitalTwinAdapter`, `CloudAdapter`, `MappingAdapter`, and `data-adapter` interfaces. To refer to these traits in your implementation, you will need to take a dependency on the `freyja-common` crate. The following `Cargo.toml` snippet shows how you can include this dependency: +Freyja supports custom implementations of the `DigitalTwinAdapter`, `CloudAdapter`, `MappingAdapter`, `DataAdapter`, and `DataAdapterFactory` interfaces. To refer to these traits in your implementation, you will need to take a dependency on the `freyja-common` crate. The following `Cargo.toml` snippet shows how you can include this dependency: ```toml [dependencies] diff --git a/docs/tutorials/quickstart.md b/docs/tutorials/quickstart.md index 7bc8a0b..00b093b 100644 --- a/docs/tutorials/quickstart.md +++ b/docs/tutorials/quickstart.md @@ -42,7 +42,7 @@ To run this sample, follow these steps: Note that with the default configuration, the mock is initialized with no mappings activated. Whenever you press Enter in the mock's terminal window, the mock's state will change to include additional mappings that will be returned by the `get_mapping` API. Using the default configuration, up to three mappings can be added one at a time when pressing Enter. -1. Run the example. To do so, run the following in the original terminal window: +1. Run the example. To do so, run the following in the original terminal window. This will build the example (if necessary) and then execute it: cargo run --example mocks