bytesandbrains_core/op.rs
1use std::fmt;
2
3/// Identifies an in-flight operation.
4///
5/// `OpId` provides a unique identifier for asynchronous operations across the
6/// system. It is used to:
7/// - Track index operations (search, add, remove, train)
8/// - Correlate distributed search operations across the network
9/// - Enable progress tracking and cancellation
10///
11/// The ID is unique within the lifetime of the component that issued it and
12/// can be used to correlate log messages, metrics, or external tracking with
13/// a specific operation.
14#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Default)]
15pub struct OpId(pub u64);
16
17impl fmt::Display for OpId {
18 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19 write!(f, "OpId({})", self.0)
20 }
21}
22
23/// A handle to an in-flight operation.
24///
25/// `OpRef` provides a unified API for both local and networked implementations:
26///
27/// - **Local implementations** can complete the work eagerly inside the method
28/// that creates the handle, making [`is_finished`](OpRef::is_finished) return
29/// `true` immediately and [`finish`](OpRef::finish) simply unwrap the
30/// pre-computed result.
31///
32/// - **Networked implementations** can return a handle that tracks a remote RPC.
33/// The caller polls [`is_finished`](OpRef::is_finished) (or awaits a
34/// notification) and calls [`finish`](OpRef::finish) once the remote side has
35/// responded.
36///
37/// This design lets generic code work identically regardless of whether the
38/// underlying operation is in-process or across a network boundary.
39pub trait OpRef {
40 /// Metadata describing the operation (e.g. query parameters, batch size).
41 type Info;
42
43 /// Runtime statistics collected during the operation (e.g. distances
44 /// computed, nodes visited).
45 type Stats;
46
47 /// The successful outcome of the operation.
48 type Result;
49
50 /// The error type returned when the operation fails.
51 type Error;
52
53 /// Returns the unique identifier assigned to this operation.
54 /// Can represent some sort of ID for the entry in an eager operation
55 /// context is up to the implementation (for example a entry tag for a local
56 /// index)
57 fn id(&self) -> &OpId;
58
59 /// Returns metadata describing the operation.
60 ///
61 /// Returns `None` if the operation no longer exists (e.g., already finished
62 /// and removed from tracking).
63 fn info(&self) -> Option<Self::Info>;
64
65 /// Returns runtime statistics collected so far.
66 ///
67 /// Returns `None` if the operation no longer exists.
68 fn stats(&self) -> Option<Self::Stats>;
69
70 /// Returns `true` once the operation has completed (successfully or not).
71 ///
72 /// For local implementations this is typically `true` immediately after
73 /// creation. For networked implementations the caller should poll this or
74 /// await a notification before calling [`finish`](OpRef::finish).
75 fn is_finished(&self) -> bool;
76
77 /// Consumes the pending operation and returns its result.
78 ///
79 /// # Errors
80 ///
81 /// Returns `Self::Error` if the operation failed.
82 fn finish(&mut self) -> Result<Self::Result, Self::Error>;
83}
84
85/// An immediate no-op operation reference.
86///
87/// Useful for protocols that don't support certain operations (e.g., bootstrap)
88/// or for stub implementations. Always returns `is_finished() == true` and
89/// `finish()` returns `Ok(())`.
90pub struct NoopOpRef {
91 id: OpId,
92}
93
94impl NoopOpRef {
95 /// Create a new no-op operation reference with the given ID.
96 pub fn new(id: u64) -> Self {
97 Self { id: OpId(id) }
98 }
99}
100
101impl OpRef for NoopOpRef {
102 type Info = ();
103 type Stats = ();
104 type Result = ();
105 type Error = std::convert::Infallible;
106
107 fn id(&self) -> &OpId {
108 &self.id
109 }
110
111 fn info(&self) -> Option<Self::Info> {
112 Some(())
113 }
114
115 fn stats(&self) -> Option<Self::Stats> {
116 Some(())
117 }
118
119 fn is_finished(&self) -> bool {
120 true
121 }
122
123 fn finish(&mut self) -> Result<Self::Result, Self::Error> {
124 Ok(())
125 }
126}