|
| 1 | +# Spawned Roadmap |
| 2 | + |
| 3 | +## Phase 1: Core Actor Framework — ✅ v0.4 |
| 4 | + |
| 5 | +- `Actor` trait with `started()` / `stopped()` lifecycle |
| 6 | +- `ActorRef<A>` for communication (`request()` and `send()`) |
| 7 | +- Dual execution modes (async tasks / sync threads) |
| 8 | +- Timers (`send_after`, `send_interval`) |
| 9 | +- Stream processing |
| 10 | +- Signal handling via `send_message_on()` |
| 11 | + |
| 12 | +## Phase 2: Type-Safe Multi-Message API — ✅ v0.5 |
| 13 | + |
| 14 | +Solved the two critical API issues (#144, #145) that blocked real-world usage: |
| 15 | + |
| 16 | +- `Handler<M>` pattern — per-message type safety, no more `unreachable!()` arms |
| 17 | +- `Recipient<M>` — type-erased handles, breaking circular dependencies between actors |
| 18 | +- `#[protocol]` macro — generates message structs, blanket impls, and `XRef` type aliases from a trait definition |
| 19 | +- `#[actor]` macro — derives `Actor` + `Handler<M>` boilerplate |
| 20 | +- Named registry — global actor lookup by name |
| 21 | + |
| 22 | +## Phase 3: Supervision Trees — in progress |
| 23 | + |
| 24 | +The missing piece for production fault tolerance. Target: v1.0.0. |
| 25 | + |
| 26 | +Following Erlang/OTP's proven design: supervisors link to children, trap exit signals, and apply restart policies. See `openspec/changes/supervision-trees/` for the full design and specs. |
| 27 | + |
| 28 | +### 3a. Exit Reasons — ✅ [PR #163](https://github.com/lambdaclass/spawned/pull/163) |
| 29 | + |
| 30 | +- `ExitReason` enum (`Normal`, `Shutdown`, `Panic(String)`, `Kill`) with `is_abnormal()` |
| 31 | +- `ActorRef::wait_exit()` and `ActorRef::exit_reason()` to observe why an actor stopped |
| 32 | +- Both tasks and threads modes |
| 33 | + |
| 34 | +### 3b. ChildHandle and ActorId — ✅ [PR #164](https://github.com/lambdaclass/spawned/pull/164) |
| 35 | + |
| 36 | +- `ActorId` — unique identity key (Spawned's equivalent of Erlang's Pid, but kept internal) |
| 37 | +- `ChildHandle` — type-erased handle to a running actor; lets supervisors manage children of any actor type uniformly |
| 38 | +- `From<ActorRef<A>> for ChildHandle` works in both execution modes |
| 39 | +- `Context::id()` and `ActorRef::id()` accessors |
| 40 | + |
| 41 | +### 3c. Monitors — next |
| 42 | + |
| 43 | +Unidirectional actor observation. Used by supervisors and any actor that wants to observe a target's death without coupling lifetimes. |
| 44 | + |
| 45 | +- **`ctx.monitor(child_handle)`** → `MonitorRef`, delivers a `Down` message via `Handler<Down>` when the target stops |
| 46 | +- **`ctx.demonitor(monitor_ref)`** — cancel a monitor |
| 47 | +- Multiple independent monitors allowed between the same pair |
| 48 | +- Monitors don't affect the monitored actor |
| 49 | + |
| 50 | +### 3d. Links and Trap Exit |
| 51 | + |
| 52 | +Bidirectional fate-sharing. Used by supervisors and for peer actors that must always run together. |
| 53 | + |
| 54 | +- **Bidirectional links** ([#131](https://github.com/lambdaclass/spawned/issues/131)) — linked actors die together; supervisors trap exits to receive `Exit` messages instead |
| 55 | +- **Atomic `start_linked(ctx)`** — prevents race between spawn and link |
| 56 | +- **`ctx.trap_exit(true)`** — converts exit signals into `Exit` messages via `Handler<Exit>` |
| 57 | +- **Kill is untrappable** — `ExitReason::Kill` bypasses trap_exit |
| 58 | + |
| 59 | +### 3e. Child Specs and Supervisor |
| 60 | + |
| 61 | +- **Child specs** ([#132](https://github.com/lambdaclass/spawned/issues/132)) — factory pattern with restart type (`Permanent`, `Transient`, `Temporary`) and shutdown type (`BrutalKill`, `Timeout`, `Infinity`) |
| 62 | +- **Supervisor actor** ([#133](https://github.com/lambdaclass/spawned/issues/133)) — `start_linked()` + `trap_exit` + `Handler<Exit>`, with strategies: OneForOne, OneForAll, RestForOne |
| 63 | +- **Meltdown protection** — sliding window restart counter; supervisor self-terminates when exceeded |
| 64 | +- **Dynamic supervisor** ([#134](https://github.com/lambdaclass/spawned/issues/134)) — add/remove children at runtime (stretch goal) |
| 65 | +- **Error handling** ([#125](https://github.com/lambdaclass/spawned/issues/125)) — proper error propagation for channel send operations |
| 66 | + |
| 67 | +## Phase 4: Documentation & Polish — pre-v1.0.0 release |
| 68 | + |
| 69 | +- Comprehensive API docs |
| 70 | +- Supervision and protocol guides |
| 71 | +- Doc tests in crate READMEs ([#137](https://github.com/lambdaclass/spawned/issues/137)) |
| 72 | +- End-to-end examples (chat server, job queue, etc.) |
| 73 | + |
| 74 | +## Future Considerations (post-v1.0) |
| 75 | + |
| 76 | +| Feature | Notes | |
| 77 | +|---------|-------| |
| 78 | +| Process groups (pg) | Erlang-style actor grouping | |
| 79 | +| Priority message channels | Signal > Stop > Supervision > Message | |
| 80 | +| State machines (`gen_statem`) | Protocol implementations | |
| 81 | +| Backoff strategies | Built into supervision (Akka pattern) | |
| 82 | +| Persistence / event sourcing | Akka Persistence pattern | |
| 83 | +| Clustering / distribution | `ractor_cluster` equivalent | |
| 84 | + |
| 85 | +## References |
| 86 | + |
| 87 | +- PR #153: v0.5 implementation |
| 88 | +- PR #154: Design research and framework comparison docs |
| 89 | +- PR #163: Exit reason tracking (Phase 3a) |
| 90 | +- PR #164: ChildHandle and ActorId (Phase 3b) |
0 commit comments