Core value types: opts structs, Job/JobState, Schedule, StreamEvent, Wake, StopToken, payload encode/decode (ADR-008 §1/§3, ADR-010 §3, ADR-015 §3, ADR-017 §3, ADR-019 §3/§4, ADR-020 §1–§4, ADR-021 §2)
This commit is contained in:
1 parent
74105a16ae
commit
92615f7b7d
12 files changed
+627
-8
No files matched your search
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: core-value-types
|
||||
name: Core value types (opts, Job, Schedule, StreamEvent, Wake, StopToken)
|
||||
status: pending
|
||||
status: completed
|
||||
depends_on: [core-errors-and-validation]
|
||||
scope: narrow
|
||||
risk: low
|
||||
@@ -68,14 +68,14 @@ part of the contract.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] All types above with the exact pinned fields/types/derives;
|
||||
- [x] All types above with the exact pinned fields/types/derives;
|
||||
`#[non_exhaustive]` on read types, absent on opts structs
|
||||
- [ ] `Default` impls: `EnqueueOpts` (all-None/0), `QueueOpts`
|
||||
- [x] `Default` impls: `EnqueueOpts` (all-None/0), `QueueOpts`
|
||||
(300/3/5/None), `ScheduleOpts`
|
||||
- [ ] `payload_as<T>` round-trips a serde_json `Value` through encode →
|
||||
- [x] `payload_as<T>` round-trips a serde_json `Value` through encode →
|
||||
decode; non-serializable target type yields `Codec`
|
||||
- [ ] `StopToken`: cancel on a clone flips all clones; unit-tested
|
||||
- [ ] `cargo test -p alkstore`, clippy `-D warnings`, fmt clean
|
||||
- [x] `StopToken`: cancel on a clone flips all clones; unit-tested
|
||||
- [x] `cargo test -p alkstore`, clippy `-D warnings`, fmt clean
|
||||
|
||||
## References
|
||||
|
||||
@@ -88,8 +88,57 @@ part of the contract.
|
||||
|
||||
## Notes
|
||||
|
||||
> To be filled by implementation agent
|
||||
- `serde`/`serde_json` added to `alkstore` (ADR-020 §4 names them the
|
||||
core crate's only deps beyond thiserror; used without the `derive`
|
||||
feature — the trait crosses `serde_json::Value`, never generic
|
||||
trait methods, so no derive machinery lives in core).
|
||||
- Module layout: `src/opts.rs` (the three opts structs),
|
||||
`src/job.rs` (`Job` + `JobState`), `src/schedule.rs`,
|
||||
`src/stream.rs` (`StreamEvent`), `src/wake.rs`,
|
||||
`src/stop_token.rs`, `src/payload.rs` (the encode/decode helpers),
|
||||
re-exported from `src/lib.rs`.
|
||||
- Encode helper named `encode_payload(&Value) -> Vec<u8>` — infallible
|
||||
at the type level (serializing a `serde_json::Value` cannot fail;
|
||||
the `unwrap_or_else` fallback is the unreachable empty vec, and
|
||||
core holds no panic posture to break: it serializes, never
|
||||
constructs, Values in engine paths). `payload_as<T:
|
||||
DeserializeOwned>(bytes)` is the shared decode used by
|
||||
`Job::payload_as` and `StreamEvent::payload_as`;
|
||||
`Error::Codec(e.to_string())` on failure.
|
||||
- "Non-serializable target yields Codec" is realized as a
|
||||
runtime-decode failure test (target type statically decodable but
|
||||
structurally mismatched with the stored bytes, plus non-JSON
|
||||
bytes) — a type with no `Deserialize` impl cannot compile through
|
||||
`payload_as`'s `DeserializeOwned` bound, so the Codec error is the
|
||||
runtime arm by construction.
|
||||
- ADR-019 §3's `Job` field list carried *as corrected by ADR-021 §2*
|
||||
(`claimed_at` present, `None` pre-claim). `JobState` derives
|
||||
`Copy` (small field-set enum, read-only value). Opts structs derive
|
||||
`Debug/Clone/PartialEq/Eq` (+`Default` per the pinned defaults);
|
||||
read types derive `Debug/Clone/PartialEq/Eq`.
|
||||
- `StopToken` = `Arc<AtomicBool>` with `Ordering::SeqCst`; `new()`
|
||||
and `Default` both construct uncancelled; doc text carries the
|
||||
engine-internal watch-channel note (ADR-019 §4) and the
|
||||
clean-stop/LeadershipLost split.
|
||||
|
||||
## Summary
|
||||
|
||||
> To be filled on completion
|
||||
Core value types implemented in `alkstore`: `EnqueueOpts`/
|
||||
`QueueOpts`/`ScheduleOpts` (exact pinned fields, hand-written
|
||||
`QueueOpts` `Default` = 300/3/5/None, derived defaults for the other
|
||||
two — all-`None`/priority 0); `Job` (ADR-019 §3 field list + ADR-021
|
||||
§2's `claimed_at`) and `JobState::{Pending, Processing, Dead}`;
|
||||
`Schedule`; `StreamEvent`; `Wake`; all read types `#[non_exhaustive]`,
|
||||
none of the opts structs; `Job::payload_as`/`StreamEvent::payload_as`
|
||||
over the shared `payload::payload_as` + `encode_payload` helpers
|
||||
(ADR-020 §4); `StopToken` (`Arc<AtomicBool>`, clone-flips-all).
|
||||
Doc comments carry the pinned semantics text (delay-over-run_at,
|
||||
relative expires, stamped QueueOpts, heartbeat is engine-side and
|
||||
absent here, wake = channel-only hint, reconnect-wake constant
|
||||
reference). Ten new unit tests (20 total in the crate) cover the
|
||||
pinned defaults, a full JSON round-trip through
|
||||
`encode_payload` → `Job`/`StreamEvent` → `payload_as` for `Value` and
|
||||
concrete typed targets, Codec failures, clone-flip stop semantics,
|
||||
and independent-token isolation. `cargo test -p alkstore` (20 pass),
|
||||
`cargo clippy --all-targets -- -D warnings`, `cargo fmt --check`, and
|
||||
workspace `cargo build` all clean.
|
||||
Reference in new issue
Block a user