Skip to content
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
99 changes: 99 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Aethernet Agent Rules

## Coding Style

- Follow **Google C++ Style Guide**.
- **Exception to IWYU:**
- If `foo.cpp` implements `foo.h`, and `foo.h` already includes a header, do NOT re-include it in `foo.cpp`.
- If `base.h` includes a header, `derived.h` should NOT re-include it.
- Always wrap `if` and `for` bodies in `{}` even if it's short one-line statement.
- Initialize variables and objects using `{}` to distinguish from function call.
- *Exception vector initialization*: In case vector must be created with size use `()` initialization to distinguish from initializer_list constructor.
- Always there is possible use `auto` for variables with respect for references `auto&` and pointers `auto*`.
- Check if pointer is null by comparing it to `nullptr` instead of using implicit conversion to `bool`.
- If function arguments is not used, there are two options. If it's never used, just ommit the argument name. If it's used on some configurations use `[[maybe_unused]]` attribute.
- Immediate lambda call pattern should be implemented by using `std::invoke`.

## Architecture & Object System

- **Core Objects (`Obj`):** Main entities (`Aether`, `Client`, `Server`, `Channel`) must inherit from `ae::Obj` and use the `AE_OBJECT` macro.
- **Smart Pointers:** Use `ae::ObjPtr<T>` for `Obj`-based classes. Use `ae::PtrView<T>` or raw pointers for weak references from runtime logic to `Obj` instances.
- **Persistence:** Use `Load`/`Save` methods and `AE_OBJECT_REFLECT` for persistent state in `Obj` classes.
- **Business Logic:** Async logic, streams, and drivers must NOT be `Obj`-based. They are "runtime" classes.

## Events and Callbacks

- Use events and callbacks to notify external code about state changes.
- If possible use callbacks set up by the constructor. If not, use event-based notifications.
- Try to pass callbacks as template parameters for better optimization.
- If not possible use SmallFunction.
- If not possible use std::function. Notice std::function makes heap allocation we trying to avoid.
- Events uses SmallFunction as a callback storage.
- Prefer setup SmallFunction by MethodPtr<&Class::method>{this} instead of lambda.
- Event subscriptions should be stored in Subscription or MultiSubscriptions class members to control subscription lifetime.
- If the class makes subscription controls lifetime of the object with event, subscription objects maybe ommited.

## Asynchrony & Tasks

### Task System

- Use task system to run tasks asynchronously.
- There is a `ManualTaskScheduler` with methods to define a single `Task` and `DelayedTask` with duration after which the task will be executed.
- To access this scheduler use `ae_context.scheduler()` method.
- Tasks should be lightweight as possible because it stored in fixed-size object pool.
- To control task lifetime use `TaskSubscription` a RAII object which automatically resets task if subscribers die.
- In rare cases class can guarantee its lifetime, subscription may be omitted.

### Stdexec

- `stdexec` library is used for chaining low-level async operations.
- whole library connected through one header `aether/executors/executors.h` and defines ex namespace alias.
- all senders should be scheduled on our Task System though ex::SchedulerOnTasks if required.
- there is three types of objects in stdexec: constructors, adapters and consumers.
- constructors are `ex::just()`, `ex::create()` or some custom senders created for specific logic.
- adapters are `ex::then()`, `ex::let_value()`, `ex::let_error()`, `ex::upon_error()` and others that transform or combine senders.
- consumers are `ex::sync_wait`, but preferred to use `ex::AnyWaiter` or `ex:AsyncWaiter`.
- se `ex::create` to create a sender from a functor to integrate c-style callbacks or other non sender logic into the executor.
- use `ex::create` if logic must test the value and set either error or value during runtime
- use `ex::variant_sender` to conditionally return either on or another sender based on some value.
- use `ex::then` `ex::upon_error` to transform from one value to another or from error to value.
- use `ex::let_value` to run new sender in chain in case of set_value.
- use `ex::let_error` to run new sender in chain in case of set_error.
- `ex::for_range` to iterate over a range of values. Internal sender must return a value, an error or stopped to end loop. To cont
- `ex::with_timeout` to add timeout to a sender chain.
- senders and adapters chained together by `|` operator.

### Actions

- Use actions to encapsulate high-level async operations.
- The `Action` maybe inherited from `Action` class which adds `is_finished()` and `finished_event()` methods.
- Each action should provide events to notify about operation progress and completion. Usually just `result_event()`.
- Actions may use senders inside to define their logic or just subscribe to another action's events.
- Actions should be managed by the class that creates them and returned by reference or pointers in case of possible null.
- If action `is_finished()` or after `finished_event()` is emitted non should have access to the action except the owner.
- Actions may be created as class members with optional or `ActionPool` or `std::unique_ptr`. But prefer to avoid allocations.


## Specific modules implementation

### AT Commands

- `at::MakeRequest(at_support, cmd, waits)` returns a pipeable adaptor — use mid-chain.
- `at::MakeRequest(ex::just(), at_support, cmd, waits)` returns a sender — use as first element or inside `ex::let_value`.
- `at::Wait("<expected>")` — build waits for the string.
- `at::Wait("<trigger>", [](auto& buffer, auto pos) { Handlers for response, must return bool })` — build waits for the string and custom handler.
- Timeouts should be implemented using `ex::with_timeout`.

## Build & Testing

Project uses cmake, tests run with `ctest`.
Project build configured in `build-clang` (`<build-dir>`) with ninja.
To build the project go into `<build-dir>/` and run `cmake --build . --parallel` or `ninja`.

To run tests, go into `<build-dir>` and run `ctest . --progress -j -E "((sodium)|(hydro)|(bcrypt)).*" --output-on-failure`.
Or run specific test by name from `<build-dir>/tests/run/<test-name>`.

To run smoke test, run `<build-dir>/aether-client-cpp-cloud`.

## Operational Rules
- Do not analyze logs until everything is working fine.
15 changes: 8 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,19 +105,20 @@ CPMAddPackage(
GIT_TAG "master"
EXCLUDE_FROM_ALL FALSE
)
# TODO: remove date
CPMAddPackage(
URI "https://github.com/HowardHinnant/date.git#master"
OPTIONS "ENABLE_DATE_INSTALL ${AE_INSTALL}"
EXCLUDE_FROM_ALL FALSE
)
CPMAddPackage(
NAME numeric
GIT_REPOSITORY "https://github.com/aethernetio/aethernet-numeric.git"
GIT_TAG "main"
OPTIONS "AE_NUMERIC_INSTALL ${AE_INSTALL}"
EXCLUDE_FROM_ALL FALSE
)
CPMAddPackage(
NAME aether-miscpp
GIT_REPOSITORY "https://github.com/aethernetio/aether-miscpp.git"
GIT_TAG "main"
OPTIONS "AE_INSTALL ${AE_INSTALL}" "AE_BUILD_TESTS ${AE_BUILD_TESTS}"
EXCLUDE_FROM_ALL FALSE
)
CPMAddPackage(
NAME etl
GIT_REPOSITORY "https://github.com/ETLCPP/etl.git"
Expand Down Expand Up @@ -152,7 +153,7 @@ target_link_libraries(${TARGET_NAME} PUBLIC
etl
stdexec
numeric
date)
aether::miscpp)

message(STATUS "Aether build for CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}")
if(CMAKE_SYSTEM_NAME STREQUAL "Linux"
Expand Down
2 changes: 1 addition & 1 deletion aether/actions/actions_queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#include <utility>
#include <functional>

#include "aether/types/small_function.h"
#include "aether-miscpp/types/small_function.h"
#include "aether/events/event_subscription.h"

namespace ae {
Expand Down
4 changes: 2 additions & 2 deletions aether/actions/repeatable_task.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
#include <functional>

#include "aether/actions/action.h"
#include "aether/meta/time_traits.h"
#include "aether/types/small_function.h"
#include "aether-miscpp/meta/time_traits.h"
#include "aether-miscpp/types/small_function.h"
#include "aether/actions/action_context.h"

namespace ae {
Expand Down
2 changes: 1 addition & 1 deletion aether/ae_actions/check_access_for_send_message.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

#include "aether/common.h"
#include "aether/types/uid.h"
#include "aether/types/result.h"
#include "aether-miscpp/types/result.h"
#include "aether/events/events.h"
#include "aether/actions/action.h"
#include "aether/cloud_connections/cloud_request.h"
Expand Down
2 changes: 1 addition & 1 deletion aether/ae_actions/get_servers.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#include <vector>

#include "aether/ae_context.h"
#include "aether/types/result.h"
#include "aether-miscpp/types/result.h"
#include "aether/events/events.h"
#include "aether/types/server_id.h"
#include "aether/actions/action.h"
Expand Down
2 changes: 1 addition & 1 deletion aether/ae_actions/select_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#include "aether/config.h"
#include "aether/ae_context.h"
#include "aether/obj/obj_ptr.h"
#include "aether/types/result.h"
#include "aether-miscpp/types/result.h"
#include "aether/events/events.h"
#include "aether/actions/action.h"
#include "aether/events/event_subscription.h"
Expand Down
2 changes: 1 addition & 1 deletion aether/ae_actions/telemetry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#if defined TELEMETRY_ENABLED

# include "aether/aether.h"
# include "aether/format/format.h"
# include "aether-miscpp/format/format.h"
# include "aether/tele/tele.h"
# include "aether/tele/traps/tele_statistics.h"

Expand Down
2 changes: 1 addition & 1 deletion aether/ae_actions/time_sync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
# include "aether/client.h"
# include "aether/aether.h"
# include "aether/uap/uap.h"
# include "aether/misc/override.h"
# include "aether-miscpp/misc/override.h"
# include "aether/types/iterator.h"
# include "aether/executors/executors.h"
# include "aether/cloud_connections/cloud_visit.h"
Expand Down
2 changes: 1 addition & 1 deletion aether/aether_app.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
#include "aether/ptr/ptr.h"
#include "aether/ptr/rc_ptr.h"
#include "aether/obj/domain.h"
#include "aether/types/small_function.h"
#include "aether-miscpp/types/small_function.h"

#include "aether/events/events.h" // IWYU pragma: keep
#include "aether/actions/action.h" // IWYU pragma: keep
Expand Down
4 changes: 2 additions & 2 deletions aether/all.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
#include "aether/events/event_subscription.h"
#include "aether/events/multi_subscription.h"

#include "aether/format/format.h"
#include "aether/reflect/reflect.h"
#include "aether-miscpp/format/format.h"
#include "aether-miscpp/reflect/reflect.h"
#include "aether/ptr/ptr.h"
#include "aether/ptr/rc_ptr.h"
#include "aether/ptr/ptr_view.h"
Expand Down
2 changes: 1 addition & 1 deletion aether/api_protocol/api_class_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#ifndef AETHER_API_PROTOCOL_API_CLASS_IMPL_H_
#define AETHER_API_PROTOCOL_API_CLASS_IMPL_H_

#include "aether/reflect/reflect.h"
#include "aether-miscpp/reflect/reflect.h"
#include "aether/api_protocol/api_class.h"
#include "aether/api_protocol/api_pack_parser.h"

Expand Down
2 changes: 1 addition & 1 deletion aether/api_protocol/api_promise.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

#include <cstdint>

#include "aether/types/result.h"
#include "aether-miscpp/types/result.h"
#include "aether/events/events.h"
#include "aether/api_protocol/request_id.h"

Expand Down
2 changes: 1 addition & 1 deletion aether/api_protocol/protocol_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include <stack>
#include <cstdint>

#include "aether/types/small_function.h"
#include "aether-miscpp/types/small_function.h"
#include "aether/api_protocol/request_id.h"

namespace ae {
Expand Down
2 changes: 1 addition & 1 deletion aether/api_protocol/request_id.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

#include <cstdint>

#include "aether/reflect/reflect.h"
#include "aether-miscpp/reflect/reflect.h"

namespace ae {
struct RequestId {
Expand Down
8 changes: 4 additions & 4 deletions aether/api_protocol/sub_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@

#include <vector>

#include "aether/meta/type_list.h"
#include "aether/reflect/reflect.h"
#include "aether/types/small_function.h"
#include "aether/meta/function_signature.h"
#include "aether-miscpp/meta/type_list.h"
#include "aether-miscpp/reflect/reflect.h"
#include "aether-miscpp/types/small_function.h"
#include "aether-miscpp/meta/function_signature.h"
#include "aether/api_protocol/api_context.h"
#include "aether/api_protocol/api_pack_parser.h"

Expand Down
2 changes: 1 addition & 1 deletion aether/channels/channels_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#include <cstddef>
#include <cstdint>

#include "aether/reflect/reflect.h"
#include "aether-miscpp/reflect/reflect.h"

namespace ae {
enum class ConnectionType : std::uint8_t {
Expand Down
2 changes: 1 addition & 1 deletion aether/cloud_connections/cloud_callbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#ifndef AETHER_CLOUD_CONNECTIONS_CLOUD_CALLBACKS_H_
#define AETHER_CLOUD_CONNECTIONS_CLOUD_CALLBACKS_H_

#include "aether/types/small_function.h"
#include "aether-miscpp/types/small_function.h"

#include "aether/events/event_deleter.h"
#include "aether/api_protocol/api_protocol.h"
Expand Down
2 changes: 1 addition & 1 deletion aether/cloud_connections/cloud_request.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

#include "aether/server.h"
#include "aether/aether.h"
#include "aether/reflect/reflect.h"
#include "aether-miscpp/reflect/reflect.h"
#include "aether/write_action/write_action.h"
#include "aether/cloud_connections/cloud_visit.h"

Expand Down
2 changes: 1 addition & 1 deletion aether/connection_manager/client_cloud_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

#include "aether/cloud.h"
#include "aether/types/uid.h"
#include "aether/types/result.h"
#include "aether-miscpp/types/result.h"
#include "aether/events/events.h"

#include "aether/ae_actions/get_servers.h"
Expand Down
Loading
Loading