1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// SPDX-License-Identifier: Apache-2.0 OR MIT
//! Live observer stream. Sibling to the audit log: the audit log is the
//! historical record (queryable via SQL); this is the push side
//! (subscribe via `Memory::subscribe`).
//!
//! Cheap to add (an empty subscriber list is free) and unlocks replication,
//! live UI, external indexers, and webhooks in future slices without engine
//! changes.
//!
//! Events are emitted **after** the SQL transaction commits. Slow subscribers
//! do not slow appends — the broadcast channel is lossy: lagged subscribers
//! receive `RecvError::Lagged(n)` and continue.
//!
//! See spec § 18.5.
use crate::memory::MemoryId;
use crate::partition::PartitionPath;
use crate::summarizer::SummaryStyle;
use crate::summary::{SummaryId, SummarySubject};
/// One push-side event.
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum MemoryEvent {
/// `Memory::append` succeeded and the SQL transaction committed.
Appended {
/// Memory id.
id: MemoryId,
/// Partition the memory was written to.
partition: PartitionPath,
/// Server-clock timestamp (unix millis).
ts_ms: i64,
},
/// `Memory::delete` succeeded.
Deleted {
/// Memory id soft-deleted.
id: MemoryId,
/// Server-clock timestamp.
ts_ms: i64,
},
/// `Memory::delete_partition` succeeded.
PartitionDeleted {
/// Partition path under which all live memories were tombstoned.
partition: PartitionPath,
/// How many rows the call tombstoned.
count: u64,
/// Server-clock timestamp.
ts_ms: i64,
},
/// `Memory::add_link` succeeded.
LinkAdded {
/// Source memory.
src: MemoryId,
/// Destination memory.
dst: MemoryId,
/// Server-clock timestamp.
ts_ms: i64,
},
/// `Memory::remove_link` succeeded.
LinkRemoved {
/// Source memory.
src: MemoryId,
/// Destination memory.
dst: MemoryId,
/// Server-clock timestamp.
ts_ms: i64,
},
/// `Memory::attach_summary` succeeded — Plan 9 first-class summary.
SummaryAttached {
/// Summary id.
id: SummaryId,
/// What the summary attaches to.
subject: SummarySubject,
/// Style preset.
style: SummaryStyle,
/// 1-indexed version.
version: u32,
/// Server-clock timestamp.
ts_ms: i64,
},
/// `Memory::delete_summary` succeeded — Plan 9 summary tombstoned.
SummaryDeleted {
/// Summary id.
id: SummaryId,
/// Server-clock timestamp.
ts_ms: i64,
},
/// A subject's `summary_stale` flag flipped on. Emitted by `Memory::append`,
/// `Memory::delete`, `Memory::delete_partition`, and
/// `Memory::mark_partition_stale`.
SummaryNeeded {
/// Subject whose summary is now stale.
subject: SummarySubject,
/// Server-clock timestamp.
ts_ms: i64,
},
/// `Memory::snapshot` succeeded — Plan 12 point-in-time freeze.
SnapshotTaken {
/// Snapshot id.
id: crate::snapshot::SnapshotId,
/// `audit_log.seq` at snapshot time.
seq: i64,
/// Server-clock timestamp.
ts_ms: i64,
},
/// `Memory::regenerate_embeddings` succeeded — Plan 12 atomic shard
/// swap. Reserved for Phase E; the variant is added now so consumers
/// can match on it without breakage when the implementation lands.
EmbeddingsRegenerated {
/// Number of memories re-embedded.
count: u64,
/// Server-clock timestamp.
ts_ms: i64,
},
/// `Memory::restore` succeeded — Plan 12 hard rollback to a snapshot.
Restored {
/// Snapshot the live set was rolled back to.
snapshot_id: crate::snapshot::SnapshotId,
/// Server-clock timestamp.
ts_ms: i64,
},
/// `Memory::migrate_scheme` succeeded — Plan 12 partition scheme
/// evolution; memory blobs were moved + indices rebuilt.
SchemeMigrated {
/// Memories whose `partition_path` changed.
memories_moved: u64,
/// Server-clock timestamp.
ts_ms: i64,
},
/// Plan 15: `Memory::set_validity` succeeded — bi-temporal validity
/// columns updated.
ValidityUpdated {
/// Memory id whose validity range moved.
id: MemoryId,
/// Server-clock timestamp.
ts_ms: i64,
},
/// Plan 16: `Memory::evolve` succeeded — atomic batch update was
/// committed.
Evolved {
/// Memory whose arrival triggered the evolution (if any).
trigger: Option<MemoryId>,
/// How many ops applied.
applied: u64,
/// New audit-log seq.
audit_seq: i64,
/// Server-clock timestamp.
ts_ms: i64,
},
}
/// Default capacity for the per-`Memory` broadcast channel.
pub const DEFAULT_EVENT_CAPACITY: usize = 1024;