use std::sync::Arc;
use std::sync::atomic::{AtomicU64, Ordering};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::completion_feed::CompletionSeq;
use crate::ops_lifecycle::OpsLifecycleRegistry;
use crate::types::SessionId;
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct RuntimeEpochId(pub Uuid);
impl RuntimeEpochId {
pub fn new() -> Self {
Self(Uuid::now_v7())
}
pub fn from_uuid(uuid: Uuid) -> Self {
Self(uuid)
}
}
impl Default for RuntimeEpochId {
fn default() -> Self {
Self::new()
}
}
impl std::fmt::Display for RuntimeEpochId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
pub struct EpochCursorState {
pub agent_applied_cursor: AtomicU64,
pub runtime_observed_seq: AtomicU64,
pub runtime_last_injected_seq: AtomicU64,
}
impl EpochCursorState {
pub fn new() -> Self {
Self {
agent_applied_cursor: AtomicU64::new(0),
runtime_observed_seq: AtomicU64::new(0),
runtime_last_injected_seq: AtomicU64::new(0),
}
}
pub fn from_recovered(
agent_applied_cursor: CompletionSeq,
runtime_observed_seq: CompletionSeq,
runtime_last_injected_seq: CompletionSeq,
) -> Self {
Self {
agent_applied_cursor: AtomicU64::new(agent_applied_cursor),
runtime_observed_seq: AtomicU64::new(runtime_observed_seq),
runtime_last_injected_seq: AtomicU64::new(runtime_last_injected_seq),
}
}
pub fn snapshot(&self) -> EpochCursorSnapshot {
EpochCursorSnapshot {
agent_applied_cursor: self.agent_applied_cursor.load(Ordering::Acquire),
runtime_observed_seq: self.runtime_observed_seq.load(Ordering::Acquire),
runtime_last_injected_seq: self.runtime_last_injected_seq.load(Ordering::Acquire),
}
}
}
impl Default for EpochCursorState {
fn default() -> Self {
Self::new()
}
}
impl std::fmt::Debug for EpochCursorState {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("EpochCursorState")
.field(
"agent_applied_cursor",
&self.agent_applied_cursor.load(Ordering::Relaxed),
)
.field(
"runtime_observed_seq",
&self.runtime_observed_seq.load(Ordering::Relaxed),
)
.field(
"runtime_last_injected_seq",
&self.runtime_last_injected_seq.load(Ordering::Relaxed),
)
.finish()
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EpochCursorSnapshot {
pub agent_applied_cursor: CompletionSeq,
pub runtime_observed_seq: CompletionSeq,
pub runtime_last_injected_seq: CompletionSeq,
}
pub struct SessionRuntimeBindings {
pub session_id: SessionId,
pub epoch_id: RuntimeEpochId,
pub ops_lifecycle: Arc<dyn OpsLifecycleRegistry>,
pub cursor_state: Arc<EpochCursorState>,
}
impl Clone for SessionRuntimeBindings {
fn clone(&self) -> Self {
Self {
session_id: self.session_id.clone(),
epoch_id: self.epoch_id.clone(),
ops_lifecycle: Arc::clone(&self.ops_lifecycle),
cursor_state: Arc::clone(&self.cursor_state),
}
}
}
impl std::fmt::Debug for SessionRuntimeBindings {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SessionRuntimeBindings")
.field("session_id", &self.session_id)
.field("epoch_id", &self.epoch_id)
.field("ops_lifecycle", &"<dyn OpsLifecycleRegistry>")
.field("cursor_state", &self.cursor_state)
.finish()
}
}
pub enum RuntimeBuildMode {
StandaloneEphemeral,
SessionOwned(SessionRuntimeBindings),
}
impl Clone for RuntimeBuildMode {
fn clone(&self) -> Self {
match self {
Self::StandaloneEphemeral => Self::StandaloneEphemeral,
Self::SessionOwned(b) => Self::SessionOwned(b.clone()),
}
}
}
impl std::fmt::Debug for RuntimeBuildMode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::StandaloneEphemeral => write!(f, "StandaloneEphemeral"),
Self::SessionOwned(b) => f
.debug_tuple("SessionOwned")
.field(&b.session_id)
.field(&b.epoch_id)
.finish(),
}
}
}