You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
88 replace spawn trait with futuresunordered (#117)
* feat: add design document for removing `Spawn` trait and refactoring of futures handling in AimDB
* Refactor AimDB to remove `Spawn` trait and collect futures in `build()`
- Updated `WebSocketConnectorImpl` to collect outbound publisher futures instead of spawning them directly.
- Refactored `ServerState` to build the WebSocket Axum server future and return it as a `BoxFuture`.
- Revised design documentation to reflect the removal of the `Spawn` trait and the new approach for handling futures.
- Modified examples to adapt to the new `build()` and `run()` pattern, ensuring proper initialization and concurrent execution of tasks.
- Removed unnecessary `Spawn` trait bounds from various components and updated related code generation.
- Cleaned up example projects to align with the new architecture, including adjustments to how the Embassy adapter is initialized and how the database runner is executed.
* feat: add configurable command channel capacity for KNX connector
* chore: update dependencies in Cargo.lock and embassy submodule
* feat: remove `Spawn` trait and update `AimDbBuilder::build()` to return `(AimDb, AimDbRunner)` across the workspace
* feat: Remove runtime parameter `R` from `Producer<T>` and `Consumer<T>`
- Updated `Producer<T, R>` to `Producer<T>` and `Consumer<T, R>` to `Consumer<T>`, simplifying user-facing signatures.
- Removed the `.key()` method from `Producer<T>`, as the record key is now captured at registration.
- Adjusted tests and examples to reflect the new type signatures.
- Updated documentation to describe the architectural changes and the motivation behind the removal of `R`.
- Ensured backward compatibility for existing async function signatures while optimizing the hot path for production and consumption of records.
* Refactor produce method to be synchronous
- Changed the `produce` method in various modules from async to synchronous, removing unnecessary await calls.
- Updated related documentation and examples to reflect the new synchronous behavior.
- Ensured that all instances of `producer.produce(value).await` were replaced with `producer.produce(value)`.
- This change simplifies the API and improves performance by eliminating the overhead of async handling where it is not needed.
* feat: simplify DewPoint production by removing await and error handling
* feat: add "macros" feature to Tokio dependency in Cargo.toml
* feat: update documentation and design notes for removing `Spawn` trait and `R` parameter from `Producer<T>` and `Consumer<T>`
* feat: add build command for remote-access-demo in Makefile and update config producer in server
* feat: update dependencies and remove alloc feature checks across the codebase
* feat: add "generic-queue-16" feature to embassy-time dependency in Cargo.toml
* feat: update embassy-time dependency to include generic-queue-16 feature for FuturesUnordered compatibility
Copy file name to clipboardExpand all lines: CHANGELOG.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -27,6 +27,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
27
27
28
28
## [Unreleased]
29
29
30
+
### Changed (breaking)
31
+
32
+
-**M13 — `Spawn` trait removed across the workspace; `AimDbBuilder::build()` now returns `(AimDb, AimDbRunner)` (Issue #88, [Design 028](docs/design/028-M13-remove-spawn-trait.md)).** Every future the database drives — producer services, taps, transforms, join forwarders, connector loops, the remote-access supervisor, `on_start` tasks — is collected at build time and driven by a single `FuturesUnordered` inside `runner.run().await`. Adapter implementations (`TokioAdapter`, `EmbassyAdapter`, `WasmAdapter`) drop their `impl Spawn`. The `embassy-task-pool-8/16/32` features are deleted and `EmbassyAdapter::new_with_network` no longer takes a `Spawner`. Connector authors must update `ConnectorBuilder::build()` to return `Vec<BoxFuture>` instead of `Arc<dyn Connector>`. See each crate's CHANGELOG for the per-crate impact.
Copy file name to clipboardExpand all lines: aimdb-codegen/CHANGELOG.md
+5Lines changed: 5 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
8
8
## [Unreleased]
9
9
10
+
### Changed (breaking)
11
+
12
+
- Emitted task scaffolds now use `Producer<T>` / `Consumer<T>` (no `, TokioAdapter` second parameter) and emitted doc tables show the same form, matching the M14 cleanup in `aimdb-core` (Design 029). Regenerate downstream scaffolds after upgrading.
13
+
- Emitted `configure_schema` signature changed from `<R: Spawn + 'static>` to `<R: RuntimeAdapter + 'static>`; emitted prelude now imports `aimdb_executor::RuntimeAdapter` instead of `Spawn` (Issue #88). Regenerate downstream schemas.
Copy file name to clipboardExpand all lines: aimdb-core/CHANGELOG.md
+32Lines changed: 32 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,6 +7,38 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
8
8
## [Unreleased]
9
9
10
+
### Changed (breaking)
11
+
12
+
-**`Producer::produce` is now sync + infallible; `Consumer::subscribe` is now infallible (Design 029 follow-up, M14).** The pre-resolved `WriteHandle::push` cannot fail and the pre-resolved buffer Arc makes `subscribe()` infallible. Call sites collapse: `producer.produce(x).await?` → `producer.produce(x);` and `let Ok(reader) = consumer.subscribe() else { ... }` → `let reader = consumer.subscribe();`. The `ProducerTrait::produce_any` / `ConsumerTrait::subscribe_any` trait surfaces stay `Result`/`async` because the type-erasure downcast remains fallible.
13
+
-`AimDb::produce<T>(key, value) -> DbResult<()>` is now sync; `.await` on the call site goes away. Only the key lookup can fail.
14
+
-`Database::produce` likewise sync.
15
+
-`TypedRecord::produce` is now `pub fn produce(&self, val: T)` (was `pub async fn produce`).
16
+
-`aimdb-wasm-adapter`: `bindings::poll_sync` helper deleted — no remaining callers now that `TypedRecord::produce` is sync.
17
+
- Dead `consumer.subscribe()` error arms in `transform/single.rs` and `transform/join.rs` removed (the `Err` branch was unreachable after M14).
18
+
19
+
-**`Producer<T>` / `Consumer<T>` drop the runtime parameter `R` and pre-resolve the record at build time (Design 029, M14).** Producer/Consumer become handles to a buffer rather than tickets to look one up: `produce()` is one virtual call (no `HashMap<key>` probe, no `TypeId` check, no downcast), and `subscribe()` collapses to `buffer.subscribe_boxed()`. The internal mechanic is a new crate-private `WriteHandle<T>` trait backed by `RecordWriter<T>` (in `aimdb-core/src/buffer/writer.rs`), pre-bound to the record's `Arc<dyn DynBuffer<T>>` + snapshot mutex + metadata tracker.
20
+
-`Producer<T, R>` → `Producer<T>`; `Consumer<T, R>` → `Consumer<T>`. User code that names the two-parameter form must drop the trailing adapter arg.
21
+
-`Producer::key(&self) -> &str` is **removed**. Capture the record key at the registration site instead.
22
+
-`Producer::produce(value) -> ()` and `Consumer::subscribe() -> Box<dyn BufferReader<T> + Send>` (v0.4 revision — see the sync/infallible bullet above for the rationale and migration). The `ProducerTrait::produce_any` / `ConsumerTrait::subscribe_any` trait surfaces retain `async`/`Result` for the type-erased downcast that can still fail.
23
+
-`AimDb::producer<T>(key)` / `AimDb::consumer<T>(key)` now return `DbResult<…>` (was infallible). They resolve the typed record up front, so callers that previously assumed inference must add `?`.
24
+
-`Consumer<T>` cannot exist without a buffer: `.tap()` on a record with no `.buffer(...)` now surfaces as `MissingConfiguration` at build time (was a deferred subscribe-time error).
25
+
-`TypedRecord::buffer` field is `Option<Arc<dyn DynBuffer<T>>>` (was `Box`); `TypedRecord::set_buffer(Box<…>)` keeps its public signature and converts via `Arc::from(box_)` internally.
26
+
-`TypedRecord::create_producer_trait(&self)` no longer takes `db` / `record_key` — it uses the new `writer_handle()`.
27
+
-`ConnectorBuilder<R>` cascade is zero-LOC: no connector struct carried `R` after M13. The outbound `consumer_factory` / inbound `producer_factory` callbacks now resolve the record once at link-startup time (via `db.inner().get_typed_record_by_key`) and construct the new handles.
28
+
- Codegen-emitted task scaffolds use `Producer<T>` / `Consumer<T>` (no `, TokioAdapter`).
29
+
-`data-contracts``log_tap` parameter is `Consumer<T>`.
30
+
31
+
-**`Spawn` trait removed; `AimDbBuilder::build()` now returns `(AimDb<R>, AimDbRunner)` (Issue #88, Design 028).** Every future the database needs — `.source()`/`.tap()`/`.transform()` tasks, on_start hooks, connector loops, the remote-access supervisor — is collected at build time into the new `AimDbRunner`, then driven by a single `FuturesUnordered` from `runner.run().await`. No background work runs until the runner is polled.
32
+
-`AimDb::spawn_task` is **deleted**. Migrate to `on_start()` (collected at build) or to a private `FuturesUnordered` inside your own future.
33
+
- The `Runtime` bundle no longer supertrait-requires `Spawn`. Custom adapters drop `impl Spawn`.
34
+
-`R: Spawn` bounds are gone everywhere in `aimdb-core` (`Producer`, `Consumer`, `TypedRecord`, `TransformDescriptor`, `RecordRegistrar`, `RecordT`, `AnyRecordExt::as_typed`, remote handler/supervisor, `Database<A>`) — replaced by `R: RuntimeAdapter`.
35
+
-`RecordSpawner<T>` renamed to `RecordFutureCollector<T>`; its `spawn_all_tasks` → `collect_all_futures`. Internal `spawn_consumer_tasks`/`spawn_producer_service`/`spawn_transform_task` on `TypedRecord` become `collect_consumer_futures`/`collect_producer_future`/`collect_transform_futures`.
36
+
- Join transforms now hoist their per-input forwarder construction to build time — `JoinPipeline::into_descriptor()` returns a `CollectedTransform { task_future, fanin_futures }` and the lazy `runtime.spawn(forwarder)` inside `run_join_transform` is gone.
37
+
-`ConnectorBuilder::build()` now returns `Vec<BoxFuture<'static, ()>>` instead of `Arc<dyn Connector>` (which `AimDbBuilder` already discarded).
38
+
- Unsafe `impl Send/Sync` blocks on `Producer<T, R>` / `Consumer<T, R>` deleted — they auto-derive now.
39
+
- On the AimX remote-access path, three `runtime.spawn(...)` call sites bridge to `tokio::spawn` directly under `#[cfg(feature = "std")]`. These (per-connection handler, per-subscription event stream, `subscribe_record_updates`) are addressed in the AimX portability follow-up.
40
+
-`on_start` no_std bifurcation collapsed: a single `StartFnType<R>` alias replaces the byte-identical std/no_std pair.
0 commit comments