pub struct CursorRegistry { /* private fields */ }Expand description
Issue #807 / PRD #750 — process-wide cursor registry for /query/stream.
On a fresh stream the server mints an opaque token, pins the read
snapshot LSN, and records it here scoped to the requesting
(tenant, principal) with a TTL. A later resume request presents the
token; resolve returns the pinned query +
snapshot only when the token is live AND the caller’s scope matches.
In-memory is acceptable for this first cut (per the issue): the registry
is shared via Arc so cloned server handles enforce against one map.
Implementations§
Source§impl CursorRegistry
impl CursorRegistry
pub fn new() -> Arc<Self> ⓘ
Sourcepub fn register(
&self,
snapshot_lsn: u64,
tenant: &str,
principal: &str,
query: &str,
entity_types: Option<Vec<String>>,
capabilities: Option<Vec<String>>,
opened_at_ms: u64,
ttl_ms: u64,
) -> String
pub fn register( &self, snapshot_lsn: u64, tenant: &str, principal: &str, query: &str, entity_types: Option<Vec<String>>, capabilities: Option<Vec<String>>, opened_at_ms: u64, ttl_ms: u64, ) -> String
Mint + record a cursor for a freshly-opened stream, returning the
opaque token handed to the client. The entry expires at
opened_at_ms + ttl_ms (saturating).
Sourcepub fn cancel_token_for(&self, token: &str) -> Option<CancelToken>
pub fn cancel_token_for(&self, token: &str) -> Option<CancelToken>
Issue #808 / 750d — clone out the shared cancel token for a cursor the caller just minted, so the live streaming handler can poll the same flag a later cancel request raises. No scope check: the only caller is the handler that owns the freshly-registered token.
Sourcepub fn cancel(
&self,
token: &str,
tenant: &str,
principal: &str,
) -> Result<CancelToken, CursorReject>
pub fn cancel( &self, token: &str, tenant: &str, principal: &str, ) -> Result<CancelToken, CursorReject>
Issue #808 / 750d — cancel + tombstone a cursor on behalf of
(tenant, principal). Raises the shared cancel token (so an
in-flight stream observing it stops) and marks the entry cancelled
so a later resume is refused with CursorReject::Cancelled.
Scope is checked exactly as in resolve:
a token owned by a different tenant/principal — or one that never
existed — returns CursorReject::NotFound so an unauthorized
caller cannot cancel, or even confirm the existence of, a foreign
stream. Cancelling an already-cancelled cursor is idempotent.
Sourcepub fn resolve(
&self,
token: &str,
tenant: &str,
principal: &str,
now_ms: u64,
) -> Result<CursorResume, CursorReject>
pub fn resolve( &self, token: &str, tenant: &str, principal: &str, now_ms: u64, ) -> Result<CursorResume, CursorReject>
Resolve a resume token for (tenant, principal) as of now_ms.
Scope is checked before expiry: a token owned by a different
tenant or principal resolves to CursorReject::NotFound —
identical to a token that was never issued — so an unauthorized
caller learns nothing about its existence. Only the rightful owner
can observe CursorReject::Expired.
Trait Implementations§
Source§impl Debug for CursorRegistry
impl Debug for CursorRegistry
Source§impl Default for CursorRegistry
impl Default for CursorRegistry
Source§fn default() -> CursorRegistry
fn default() -> CursorRegistry
Auto Trait Implementations§
impl !Freeze for CursorRegistry
impl RefUnwindSafe for CursorRegistry
impl Send for CursorRegistry
impl Sync for CursorRegistry
impl Unpin for CursorRegistry
impl UnsafeUnpin for CursorRegistry
impl UnwindSafe for CursorRegistry
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request