2026-08-22 17:16:56 +00:00
|
|
|
//! Authoritative virtual blob namespace actor and restart-tolerant client proxy.
|
|
|
|
|
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
use std::collections::{BTreeMap, HashMap, HashSet, VecDeque};
|
2026-08-22 17:16:56 +00:00
|
|
|
use std::fmt;
|
|
|
|
|
use std::path::Path;
|
|
|
|
|
use std::sync::Arc;
|
|
|
|
|
use std::sync::atomic::{AtomicU64, Ordering};
|
|
|
|
|
use std::time::Duration;
|
|
|
|
|
|
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
use swactor::actor::{ActorAddress, ActorInterface, Ctx};
|
|
|
|
|
use swactor::runtime::{ExternalSender, Runtime};
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
use swactor_engine::{ActorTimer, EngineHandle, EngineInstant};
|
2026-08-22 17:16:56 +00:00
|
|
|
use swactor_transport::{CodecRegistry, JsonCodec, NetworkMessage};
|
|
|
|
|
|
|
|
|
|
use crate::blob_transfer::{BlobTransferEvent, BlobTransferId};
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
use crate::host::{HostRouteRegistrar, HostRouteWatch};
|
2026-08-22 17:16:56 +00:00
|
|
|
use crate::namespace_store::{
|
|
|
|
|
MutationReceipt, MutationRejection, MutationRequest, NamespaceStore, NamespaceStoreError,
|
|
|
|
|
PersistedBinding, PersistedMutationResult, PersistedOperation,
|
|
|
|
|
};
|
|
|
|
|
use crate::path::DataPath;
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
use crate::protocol::HostStreamIn;
|
2026-08-22 17:16:56 +00:00
|
|
|
use crate::source::BlobSourceIn;
|
|
|
|
|
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
const RETIREMENT_RETRY_BATCH: usize = 32;
|
|
|
|
|
|
2026-08-22 17:16:56 +00:00
|
|
|
pub use crate::namespace_store::{OperationId, SourceRecovery};
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
|
|
|
pub struct DirectoryRequestId(pub u64);
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
|
|
|
pub struct BlobBinding {
|
|
|
|
|
pub source: ActorAddress,
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
pub source_node: [u8; 32],
|
|
|
|
|
pub owner: Option<ActorAddress>,
|
2026-08-22 17:16:56 +00:00
|
|
|
pub length: u64,
|
|
|
|
|
pub revision: u64,
|
|
|
|
|
}
|
|
|
|
|
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
|
|
|
pub enum EntryKind {
|
|
|
|
|
Blob,
|
|
|
|
|
Stream,
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-24 15:22:20 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
|
|
|
pub struct NamespaceNode {
|
|
|
|
|
pub kind: EntryKind,
|
|
|
|
|
pub revision: u64,
|
2026-08-27 22:09:26 +00:00
|
|
|
pub active: bool,
|
2026-08-24 15:22:20 +00:00
|
|
|
}
|
|
|
|
|
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
|
|
|
pub enum StreamRole {
|
|
|
|
|
Source,
|
|
|
|
|
Sink,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
|
|
|
|
|
pub struct StreamIncarnation {
|
|
|
|
|
pub authority_epoch: u64,
|
|
|
|
|
pub revision: u64,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
|
|
|
pub struct StreamMatch {
|
|
|
|
|
pub incarnation: StreamIncarnation,
|
|
|
|
|
pub source: ActorAddress,
|
|
|
|
|
pub source_descriptor: Vec<u8>,
|
|
|
|
|
pub sink_descriptor: Vec<u8>,
|
|
|
|
|
pub sink: ActorAddress,
|
|
|
|
|
pub revision: u64,
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-22 17:16:56 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
|
|
|
pub enum NamespaceError {
|
|
|
|
|
PathNotFound(DataPath),
|
2026-08-24 15:22:20 +00:00
|
|
|
PathExists(DataPath),
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
WrongEntryType {
|
|
|
|
|
path: DataPath,
|
|
|
|
|
expected: EntryKind,
|
|
|
|
|
found: EntryKind,
|
|
|
|
|
},
|
|
|
|
|
PathReplaced(DataPath),
|
|
|
|
|
DuplicateStreamRole {
|
|
|
|
|
path: DataPath,
|
|
|
|
|
role: StreamRole,
|
|
|
|
|
},
|
|
|
|
|
StaleIncarnation {
|
|
|
|
|
path: DataPath,
|
|
|
|
|
incarnation: StreamIncarnation,
|
|
|
|
|
},
|
2026-08-22 17:16:56 +00:00
|
|
|
OperationConflict(OperationId),
|
2026-08-27 22:09:26 +00:00
|
|
|
StreamActive(DataPath),
|
2026-08-22 17:16:56 +00:00
|
|
|
Storage(String),
|
|
|
|
|
SourceRecovery(String),
|
|
|
|
|
DirectoryUnavailable(String),
|
|
|
|
|
Protocol(String),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl fmt::Display for NamespaceError {
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
|
match self {
|
|
|
|
|
Self::PathNotFound(path) => write!(f, "data path not found: {path}"),
|
2026-08-24 15:22:20 +00:00
|
|
|
Self::PathExists(path) => write!(f, "data path already exists: {path}"),
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
Self::WrongEntryType {
|
|
|
|
|
path,
|
|
|
|
|
expected,
|
|
|
|
|
found,
|
|
|
|
|
} => write!(
|
|
|
|
|
f,
|
|
|
|
|
"data path {path} has entry kind {found:?}, expected {expected:?}"
|
|
|
|
|
),
|
|
|
|
|
Self::PathReplaced(path) => {
|
|
|
|
|
write!(f, "pending data path was replaced: {path}")
|
|
|
|
|
}
|
|
|
|
|
Self::DuplicateStreamRole { path, role } => {
|
|
|
|
|
write!(f, "stream path {path} already has a {role:?}")
|
|
|
|
|
}
|
|
|
|
|
Self::StaleIncarnation { path, incarnation } => write!(
|
|
|
|
|
f,
|
|
|
|
|
"stream path {path} no longer names incarnation {}:{}",
|
|
|
|
|
incarnation.authority_epoch, incarnation.revision
|
|
|
|
|
),
|
2026-08-22 17:16:56 +00:00
|
|
|
Self::OperationConflict(operation) => write!(
|
|
|
|
|
f,
|
|
|
|
|
"namespace operation ID {:02x?} was reused for a different request",
|
|
|
|
|
operation.bytes()
|
|
|
|
|
),
|
2026-08-27 22:09:26 +00:00
|
|
|
Self::StreamActive(path) => {
|
|
|
|
|
write!(f, "stream path {path} has active or pending endpoints")
|
|
|
|
|
}
|
2026-08-22 17:16:56 +00:00
|
|
|
Self::Storage(reason) => write!(f, "namespace persistence failed: {reason}"),
|
|
|
|
|
Self::SourceRecovery(reason) => write!(f, "namespace source recovery failed: {reason}"),
|
|
|
|
|
Self::DirectoryUnavailable(reason) => {
|
|
|
|
|
write!(f, "namespace directory is unavailable: {reason}")
|
|
|
|
|
}
|
|
|
|
|
Self::Protocol(reason) => write!(f, "namespace protocol failed: {reason}"),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl std::error::Error for NamespaceError {}
|
|
|
|
|
|
|
|
|
|
impl From<NamespaceStoreError> for NamespaceError {
|
|
|
|
|
fn from(error: NamespaceStoreError) -> Self {
|
|
|
|
|
Self::Storage(error.to_string())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
|
|
|
pub enum DataDirectoryIn {
|
|
|
|
|
Register {
|
|
|
|
|
request_id: DirectoryRequestId,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
source: ActorAddress,
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
source_node: [u8; 32],
|
2026-08-22 17:16:56 +00:00
|
|
|
length: u64,
|
|
|
|
|
recovery: SourceRecovery,
|
|
|
|
|
operation_id: OperationId,
|
2026-08-24 15:22:20 +00:00
|
|
|
reservation: Option<OperationId>,
|
2026-08-22 17:16:56 +00:00
|
|
|
reply_to: ActorAddress,
|
|
|
|
|
},
|
|
|
|
|
Resolve {
|
|
|
|
|
request_id: DirectoryRequestId,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
reply_to: ActorAddress,
|
|
|
|
|
},
|
2026-08-24 15:22:20 +00:00
|
|
|
Lookup {
|
|
|
|
|
request_id: DirectoryRequestId,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
reply_to: ActorAddress,
|
|
|
|
|
},
|
|
|
|
|
ReserveBlob {
|
|
|
|
|
request_id: DirectoryRequestId,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
reply_to: ActorAddress,
|
|
|
|
|
},
|
|
|
|
|
ReleaseBlobReservation {
|
|
|
|
|
request_id: DirectoryRequestId,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
reply_to: ActorAddress,
|
|
|
|
|
},
|
2026-08-22 17:16:56 +00:00
|
|
|
Unregister {
|
|
|
|
|
request_id: DirectoryRequestId,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
reply_to: ActorAddress,
|
|
|
|
|
},
|
2026-08-27 22:09:26 +00:00
|
|
|
Rename {
|
|
|
|
|
request_id: DirectoryRequestId,
|
|
|
|
|
source: DataPath,
|
|
|
|
|
destination: DataPath,
|
|
|
|
|
replace: bool,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
reply_to: ActorAddress,
|
|
|
|
|
},
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
OpenStream {
|
|
|
|
|
request_id: DirectoryRequestId,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
role: StreamRole,
|
|
|
|
|
descriptor: Vec<u8>,
|
|
|
|
|
endpoint: ActorAddress,
|
|
|
|
|
replace: bool,
|
2026-08-24 15:22:20 +00:00
|
|
|
ensure: bool,
|
|
|
|
|
expected_revision: Option<u64>,
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
operation_id: OperationId,
|
|
|
|
|
reply_to: ActorAddress,
|
|
|
|
|
},
|
|
|
|
|
CancelStream {
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
request_id: DirectoryRequestId,
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
path: DataPath,
|
|
|
|
|
operation_id: OperationId,
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
reply_to: Option<ActorAddress>,
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
},
|
|
|
|
|
CloseStream {
|
|
|
|
|
request_id: DirectoryRequestId,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
incarnation: StreamIncarnation,
|
|
|
|
|
reply_to: ActorAddress,
|
|
|
|
|
},
|
2026-08-27 22:09:26 +00:00
|
|
|
SourceRetired {
|
|
|
|
|
source: ActorAddress,
|
|
|
|
|
},
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
StreamDisplaced {
|
|
|
|
|
endpoint: ActorAddress,
|
|
|
|
|
incarnation: StreamIncarnation,
|
|
|
|
|
},
|
2026-08-27 22:09:26 +00:00
|
|
|
/// Periodic self-tick that re-drives pending retirements. Retire is a
|
|
|
|
|
/// lifecycle one-shot over an at-most-once transport; without traffic
|
|
|
|
|
/// that re-runs [`DataDirectoryActor`]'s retry pass, a single lost frame
|
|
|
|
|
/// strands the retired source and its published binding forever.
|
|
|
|
|
RetryRetirements,
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
/// Local observation: re-drive only this still-pending obligation.
|
|
|
|
|
RetirementRouteChanged {
|
|
|
|
|
target: ActorAddress,
|
|
|
|
|
},
|
2026-08-22 17:16:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl NetworkMessage for DataDirectoryIn {
|
|
|
|
|
fn type_tag() -> &'static str {
|
|
|
|
|
"data-plane.data-directory.in.v1"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
|
|
|
pub enum DataDirectoryOut {
|
|
|
|
|
Registered {
|
|
|
|
|
request_id: DirectoryRequestId,
|
|
|
|
|
authority_epoch: u64,
|
|
|
|
|
result: Result<MutationReceipt, NamespaceError>,
|
|
|
|
|
},
|
|
|
|
|
Resolved {
|
|
|
|
|
request_id: DirectoryRequestId,
|
|
|
|
|
authority_epoch: u64,
|
|
|
|
|
result: Result<BlobBinding, NamespaceError>,
|
|
|
|
|
},
|
2026-08-24 15:22:20 +00:00
|
|
|
LookedUp {
|
|
|
|
|
request_id: DirectoryRequestId,
|
|
|
|
|
authority_epoch: u64,
|
|
|
|
|
result: Result<NamespaceNode, NamespaceError>,
|
|
|
|
|
},
|
|
|
|
|
BlobReserved {
|
|
|
|
|
request_id: DirectoryRequestId,
|
|
|
|
|
authority_epoch: u64,
|
|
|
|
|
result: Result<(), NamespaceError>,
|
|
|
|
|
},
|
|
|
|
|
BlobReservationReleased {
|
|
|
|
|
request_id: DirectoryRequestId,
|
|
|
|
|
authority_epoch: u64,
|
|
|
|
|
result: Result<(), NamespaceError>,
|
|
|
|
|
},
|
2026-08-22 17:16:56 +00:00
|
|
|
Unregistered {
|
|
|
|
|
request_id: DirectoryRequestId,
|
|
|
|
|
authority_epoch: u64,
|
|
|
|
|
result: Result<MutationReceipt, NamespaceError>,
|
|
|
|
|
},
|
2026-08-27 22:09:26 +00:00
|
|
|
Renamed {
|
|
|
|
|
request_id: DirectoryRequestId,
|
|
|
|
|
authority_epoch: u64,
|
|
|
|
|
result: Result<MutationReceipt, NamespaceError>,
|
|
|
|
|
},
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
StreamOpened {
|
|
|
|
|
request_id: DirectoryRequestId,
|
|
|
|
|
authority_epoch: u64,
|
|
|
|
|
result: Result<StreamMatch, NamespaceError>,
|
|
|
|
|
},
|
|
|
|
|
StreamClosed {
|
|
|
|
|
request_id: DirectoryRequestId,
|
|
|
|
|
authority_epoch: u64,
|
|
|
|
|
result: Result<(), NamespaceError>,
|
|
|
|
|
},
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
StreamCancelled {
|
|
|
|
|
request_id: DirectoryRequestId,
|
|
|
|
|
authority_epoch: u64,
|
|
|
|
|
result: Result<(), NamespaceError>,
|
|
|
|
|
},
|
2026-08-22 17:16:56 +00:00
|
|
|
}
|
|
|
|
|
impl DataDirectoryOut {
|
|
|
|
|
pub fn request_id(&self) -> DirectoryRequestId {
|
|
|
|
|
match self {
|
|
|
|
|
Self::Registered { request_id, .. }
|
|
|
|
|
| Self::Resolved { request_id, .. }
|
2026-08-24 15:22:20 +00:00
|
|
|
| Self::LookedUp { request_id, .. }
|
|
|
|
|
| Self::BlobReserved { request_id, .. }
|
|
|
|
|
| Self::BlobReservationReleased { request_id, .. }
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
| Self::Unregistered { request_id, .. }
|
2026-08-27 22:09:26 +00:00
|
|
|
| Self::Renamed { request_id, .. }
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
| Self::StreamOpened { request_id, .. }
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
| Self::StreamClosed { request_id, .. }
|
|
|
|
|
| Self::StreamCancelled { request_id, .. } => *request_id,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn authority_epoch(&self) -> u64 {
|
|
|
|
|
match self {
|
|
|
|
|
Self::Registered {
|
|
|
|
|
authority_epoch, ..
|
|
|
|
|
}
|
|
|
|
|
| Self::Resolved {
|
|
|
|
|
authority_epoch, ..
|
|
|
|
|
}
|
|
|
|
|
| Self::LookedUp {
|
|
|
|
|
authority_epoch, ..
|
|
|
|
|
}
|
|
|
|
|
| Self::BlobReserved {
|
|
|
|
|
authority_epoch, ..
|
|
|
|
|
}
|
|
|
|
|
| Self::BlobReservationReleased {
|
|
|
|
|
authority_epoch, ..
|
|
|
|
|
}
|
|
|
|
|
| Self::Unregistered {
|
|
|
|
|
authority_epoch, ..
|
|
|
|
|
}
|
|
|
|
|
| Self::Renamed {
|
|
|
|
|
authority_epoch, ..
|
|
|
|
|
}
|
|
|
|
|
| Self::StreamOpened {
|
|
|
|
|
authority_epoch, ..
|
|
|
|
|
}
|
|
|
|
|
| Self::StreamClosed {
|
|
|
|
|
authority_epoch, ..
|
|
|
|
|
}
|
|
|
|
|
| Self::StreamCancelled {
|
|
|
|
|
authority_epoch, ..
|
|
|
|
|
} => *authority_epoch,
|
2026-08-22 17:16:56 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
|
|
|
pub enum NamespaceRequest {
|
|
|
|
|
Register {
|
|
|
|
|
path: DataPath,
|
|
|
|
|
source: ActorAddress,
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
source_node: [u8; 32],
|
2026-08-22 17:16:56 +00:00
|
|
|
length: u64,
|
|
|
|
|
recovery: SourceRecovery,
|
|
|
|
|
operation_id: OperationId,
|
2026-08-24 15:22:20 +00:00
|
|
|
reservation: Option<OperationId>,
|
2026-08-22 17:16:56 +00:00
|
|
|
},
|
|
|
|
|
Resolve {
|
|
|
|
|
path: DataPath,
|
|
|
|
|
},
|
2026-08-24 15:22:20 +00:00
|
|
|
Lookup {
|
|
|
|
|
path: DataPath,
|
|
|
|
|
},
|
|
|
|
|
ReserveBlob {
|
|
|
|
|
path: DataPath,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
},
|
|
|
|
|
ReleaseBlobReservation {
|
|
|
|
|
path: DataPath,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
},
|
2026-08-22 17:16:56 +00:00
|
|
|
Unregister {
|
|
|
|
|
path: DataPath,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
},
|
2026-08-27 22:09:26 +00:00
|
|
|
Rename {
|
|
|
|
|
source: DataPath,
|
|
|
|
|
destination: DataPath,
|
|
|
|
|
replace: bool,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
},
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
OpenStream {
|
|
|
|
|
path: DataPath,
|
|
|
|
|
role: StreamRole,
|
|
|
|
|
endpoint: ActorAddress,
|
|
|
|
|
descriptor: Vec<u8>,
|
|
|
|
|
replace: bool,
|
2026-08-24 15:22:20 +00:00
|
|
|
ensure: bool,
|
|
|
|
|
expected_revision: Option<u64>,
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
operation_id: OperationId,
|
|
|
|
|
},
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
CancelStream {
|
|
|
|
|
path: DataPath,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
},
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
CloseStream {
|
|
|
|
|
path: DataPath,
|
|
|
|
|
incarnation: StreamIncarnation,
|
|
|
|
|
},
|
2026-08-22 17:16:56 +00:00
|
|
|
}
|
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
|
|
|
pub enum NamespaceClientIn {
|
|
|
|
|
Request {
|
|
|
|
|
request: NamespaceRequest,
|
|
|
|
|
reply_to: ActorAddress,
|
|
|
|
|
},
|
|
|
|
|
Cancel {
|
|
|
|
|
reply_to: ActorAddress,
|
|
|
|
|
},
|
2026-08-24 15:22:20 +00:00
|
|
|
CancelBlobReservation {
|
|
|
|
|
path: DataPath,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
reply_to: ActorAddress,
|
|
|
|
|
},
|
2026-08-22 17:16:56 +00:00
|
|
|
DirectoryReply(DataDirectoryOut),
|
|
|
|
|
TransferFailed {
|
|
|
|
|
destination: ActorAddress,
|
|
|
|
|
transfer_id: BlobTransferId,
|
|
|
|
|
reason: String,
|
|
|
|
|
},
|
|
|
|
|
Retry,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl NetworkMessage for NamespaceClientIn {
|
|
|
|
|
fn type_tag() -> &'static str {
|
|
|
|
|
"data-plane.namespace-client.in.v1"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
|
enum RuntimeSource {
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
Available {
|
|
|
|
|
actor: ActorAddress,
|
|
|
|
|
node: [u8; 32],
|
|
|
|
|
owner: Option<ActorAddress>,
|
|
|
|
|
},
|
2026-08-22 17:16:56 +00:00
|
|
|
Unavailable(String),
|
|
|
|
|
}
|
|
|
|
|
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
struct PendingStream {
|
|
|
|
|
role: StreamRole,
|
|
|
|
|
endpoint: ActorAddress,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
request_id: DirectoryRequestId,
|
|
|
|
|
descriptor: Vec<u8>,
|
|
|
|
|
reply_to: ActorAddress,
|
|
|
|
|
revision: u64,
|
2026-08-24 15:22:20 +00:00
|
|
|
opened_from_revision: Option<u64>,
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct StreamOpenRequest {
|
|
|
|
|
request_id: DirectoryRequestId,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
role: StreamRole,
|
|
|
|
|
endpoint: ActorAddress,
|
|
|
|
|
replace: bool,
|
2026-08-24 15:22:20 +00:00
|
|
|
ensure: bool,
|
|
|
|
|
expected_revision: Option<u64>,
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
descriptor: Vec<u8>,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
reply_to: ActorAddress,
|
|
|
|
|
}
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
|
|
|
|
|
struct StreamReplacementFence {
|
|
|
|
|
incarnation: StreamIncarnation,
|
|
|
|
|
endpoints: HashSet<ActorAddress>,
|
|
|
|
|
old: Option<ActiveStream>,
|
|
|
|
|
requests: Vec<StreamOpenRequest>,
|
|
|
|
|
}
|
2026-08-27 22:09:26 +00:00
|
|
|
struct BlobRegistration {
|
|
|
|
|
path: DataPath,
|
|
|
|
|
source: ActorAddress,
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
source_node: [u8; 32],
|
2026-08-27 22:09:26 +00:00
|
|
|
length: u64,
|
|
|
|
|
recovery: SourceRecovery,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
reservation: Option<OperationId>,
|
|
|
|
|
retired: Option<ActorAddress>,
|
|
|
|
|
}
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
|
|
|
|
|
struct ActiveStream {
|
|
|
|
|
binding: StreamMatch,
|
|
|
|
|
source_operation: OperationId,
|
|
|
|
|
sink_operation: OperationId,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum RuntimeStream {
|
|
|
|
|
Pending(PendingStream),
|
|
|
|
|
Active(ActiveStream),
|
|
|
|
|
}
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
|
|
|
|
|
struct PendingStreamDisplacement {
|
|
|
|
|
incarnation: StreamIncarnation,
|
|
|
|
|
// Once the endpoint acknowledges it may stop, so only durability remains
|
|
|
|
|
// retryable. Keep the acknowledgement until that commit succeeds.
|
|
|
|
|
acknowledged: bool,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl PendingStreamDisplacement {
|
|
|
|
|
/// Returns true only when the acknowledged obligation is durably complete.
|
|
|
|
|
fn retry(&self, ctx: &Ctx<'_>, endpoint: ActorAddress, store: &mut NamespaceStore) -> bool {
|
|
|
|
|
if !self.acknowledged {
|
|
|
|
|
let _ = ctx.send(
|
|
|
|
|
endpoint,
|
|
|
|
|
HostStreamIn::Displaced {
|
|
|
|
|
incarnation: self.incarnation,
|
|
|
|
|
reply_to: Some(ctx.self_addr()),
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
let mut next = store.snapshot().clone();
|
|
|
|
|
next.stream_retirements
|
|
|
|
|
.retain(|(known, _)| *known != endpoint);
|
|
|
|
|
if let Err(error) = store.commit(next) {
|
|
|
|
|
eprintln!("data-directory: retiring stream displacement failed: {error}");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-22 17:16:56 +00:00
|
|
|
pub struct DataDirectoryActor {
|
|
|
|
|
store: NamespaceStore,
|
|
|
|
|
sources: BTreeMap<DataPath, RuntimeSource>,
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
streams: BTreeMap<DataPath, RuntimeStream>,
|
2026-08-24 15:22:20 +00:00
|
|
|
blob_reservations: BTreeMap<DataPath, OperationId>,
|
2026-08-27 22:09:26 +00:00
|
|
|
pending_retirements: HashSet<ActorAddress>,
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
pending_stream_displacements: HashMap<ActorAddress, PendingStreamDisplacement>,
|
|
|
|
|
stream_replacement_fences: BTreeMap<DataPath, StreamReplacementFence>,
|
2026-08-22 17:16:56 +00:00
|
|
|
authority_epoch: u64,
|
2026-08-27 22:09:26 +00:00
|
|
|
retire_retry: Option<RetirementRetry>,
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
retirement_watches: HashMap<ActorAddress, HostRouteWatch>,
|
|
|
|
|
retirement_retry_queue: VecDeque<ActorAddress>,
|
|
|
|
|
retirement_timer: Option<ActorTimer>,
|
|
|
|
|
#[cfg(feature = "directory-trace")]
|
|
|
|
|
trace: DirectoryTrace,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Load-diagnostic counters for the directory actor (compiled in only with
|
|
|
|
|
/// the `directory-trace` feature). Production builds carry no cost.
|
|
|
|
|
#[cfg(feature = "directory-trace")]
|
|
|
|
|
pub struct DirectoryTrace {
|
|
|
|
|
messages: u64,
|
|
|
|
|
retire_fans: u64,
|
|
|
|
|
last_report: std::time::Instant,
|
|
|
|
|
last_commits: u64,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "directory-trace")]
|
|
|
|
|
impl DirectoryTrace {
|
|
|
|
|
fn emit(line: String) {
|
|
|
|
|
use std::io::Write;
|
|
|
|
|
eprintln!("{line}");
|
|
|
|
|
if let Ok(mut file) = std::fs::OpenOptions::new()
|
|
|
|
|
.create(true)
|
|
|
|
|
.append(true)
|
|
|
|
|
.open("target/dir-trace.log")
|
|
|
|
|
{
|
|
|
|
|
let _ = writeln!(file, "{line}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
fn new() -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
messages: 0,
|
|
|
|
|
retire_fans: 0,
|
|
|
|
|
last_report: std::time::Instant::now(),
|
|
|
|
|
last_commits: crate::namespace_store::trace_commit_count(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Aggregate one message-handling step; print a summary every 2 seconds.
|
|
|
|
|
fn observed_step(&mut self, pending_retirements: usize, store: &NamespaceStore) {
|
|
|
|
|
self.messages += 1;
|
|
|
|
|
if self.last_report.elapsed() >= Duration::from_secs(2) {
|
|
|
|
|
let snapshot = store.snapshot();
|
|
|
|
|
let commits = crate::namespace_store::trace_commit_count();
|
|
|
|
|
let elapsed = self.last_report.elapsed().as_secs_f64().max(0.001);
|
|
|
|
|
Self::emit(format!(
|
|
|
|
|
"[dir-trace] msgs={} ({:.0}/s) retire_fans={} ({:.0}/s) pending_retire={} \
|
|
|
|
|
persisted_retire={} ops={} bindings={} stream_nodes={} commits={} ({:.0}/s) \
|
|
|
|
|
avg_commit={:.1}ms worst_commit={:.1}ms",
|
|
|
|
|
self.messages,
|
|
|
|
|
self.messages as f64 / elapsed,
|
|
|
|
|
self.retire_fans,
|
|
|
|
|
self.retire_fans as f64 / elapsed,
|
|
|
|
|
pending_retirements,
|
|
|
|
|
snapshot.retirements.len(),
|
|
|
|
|
snapshot.operations.len(),
|
|
|
|
|
snapshot.bindings.len(),
|
|
|
|
|
snapshot.stream_nodes.len(),
|
|
|
|
|
commits,
|
|
|
|
|
(commits - self.last_commits) as f64 / elapsed,
|
|
|
|
|
crate::namespace_store::trace_commit_avg_ms(),
|
|
|
|
|
crate::namespace_store::trace_commit_worst_ms(),
|
|
|
|
|
));
|
|
|
|
|
self.last_commits = commits;
|
|
|
|
|
self.last_report = std::time::Instant::now();
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-08-27 22:09:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Engine-hosted periodic tick that re-sends pending `Retire` messages.
|
|
|
|
|
///
|
|
|
|
|
/// Retire frames are fire-and-forget: a write onto a connection that dies
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
/// mid-flight is dropped without feedback. The tick is the only periodic
|
|
|
|
|
/// re-drive of pending retirements: re-fanning on every inbound message
|
|
|
|
|
/// would couple the outbound Retire rate to the cluster's request rate, and
|
|
|
|
|
/// a loaded directory multiplied each unacknowledged retirement into a
|
|
|
|
|
/// self-sustaining frame storm. The tick keeps the retry pass running at a
|
|
|
|
|
/// fixed cadence until each retirement is acknowledged; a fresh retirement
|
|
|
|
|
/// is also sent immediately at enqueue time.
|
2026-08-27 22:09:26 +00:00
|
|
|
pub struct RetirementRetry {
|
|
|
|
|
engine: EngineHandle,
|
|
|
|
|
sender: ExternalSender,
|
|
|
|
|
period: Duration,
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
routes: Option<Arc<dyn HostRouteRegistrar>>,
|
2026-08-27 22:09:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl RetirementRetry {
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
pub fn new(
|
|
|
|
|
engine: EngineHandle,
|
|
|
|
|
sender: ExternalSender,
|
|
|
|
|
period: Duration,
|
|
|
|
|
routes: Option<Arc<dyn HostRouteRegistrar>>,
|
|
|
|
|
) -> Self {
|
2026-08-27 22:09:26 +00:00
|
|
|
Self {
|
|
|
|
|
engine,
|
|
|
|
|
sender,
|
|
|
|
|
period,
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
routes,
|
2026-08-27 22:09:26 +00:00
|
|
|
}
|
|
|
|
|
}
|
2026-08-22 17:16:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl DataDirectoryActor {
|
|
|
|
|
pub fn recover(
|
|
|
|
|
store_path: impl AsRef<Path>,
|
2026-08-27 22:09:26 +00:00
|
|
|
retire_retry: Option<RetirementRetry>,
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
mut recover_source: impl FnMut(
|
|
|
|
|
&SourceRecovery,
|
|
|
|
|
u64,
|
|
|
|
|
) -> Result<(ActorAddress, [u8; 32]), NamespaceError>,
|
2026-08-22 17:16:56 +00:00
|
|
|
) -> Result<Self, NamespaceError> {
|
|
|
|
|
let mut store = NamespaceStore::open(store_path)?;
|
|
|
|
|
let bindings = store.snapshot().bindings.clone();
|
|
|
|
|
let mut sources = BTreeMap::new();
|
|
|
|
|
for (path, binding) in bindings {
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
let owner = match &binding.recovery {
|
|
|
|
|
SourceRecovery::Actor { owner, .. } => *owner,
|
|
|
|
|
SourceRecovery::File { .. } => None,
|
|
|
|
|
};
|
2026-08-22 17:16:56 +00:00
|
|
|
let source = match recover_source(&binding.recovery, binding.length) {
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
Ok((actor, node)) => RuntimeSource::Available { actor, node, owner },
|
2026-08-22 17:16:56 +00:00
|
|
|
Err(error) => RuntimeSource::Unavailable(error.to_string()),
|
|
|
|
|
};
|
|
|
|
|
sources.insert(path, source);
|
|
|
|
|
}
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
let pending_retirements: HashSet<_> =
|
|
|
|
|
store.snapshot().retirements.iter().copied().collect();
|
|
|
|
|
let retirement_retry_queue = pending_retirements.iter().copied().collect();
|
|
|
|
|
let pending_stream_displacements = store
|
|
|
|
|
.snapshot()
|
|
|
|
|
.stream_retirements
|
|
|
|
|
.iter()
|
|
|
|
|
.map(|(endpoint, incarnation)| {
|
|
|
|
|
(
|
|
|
|
|
*endpoint,
|
|
|
|
|
PendingStreamDisplacement {
|
|
|
|
|
incarnation: *incarnation,
|
|
|
|
|
acknowledged: false,
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
.collect();
|
|
|
|
|
let mut stream_replacement_fences = BTreeMap::new();
|
|
|
|
|
for (endpoint, incarnation) in &store.snapshot().stream_retirements {
|
|
|
|
|
let Some((path, _)) = store
|
|
|
|
|
.snapshot()
|
|
|
|
|
.stream_nodes
|
|
|
|
|
.iter()
|
|
|
|
|
.find(|(_, revision)| **revision == incarnation.revision)
|
|
|
|
|
else {
|
|
|
|
|
continue;
|
|
|
|
|
};
|
|
|
|
|
let fence = stream_replacement_fences
|
|
|
|
|
.entry(path.clone())
|
|
|
|
|
.or_insert_with(|| StreamReplacementFence {
|
|
|
|
|
incarnation: *incarnation,
|
|
|
|
|
endpoints: HashSet::new(),
|
|
|
|
|
old: None,
|
|
|
|
|
requests: Vec::new(),
|
|
|
|
|
});
|
|
|
|
|
if fence.incarnation == *incarnation {
|
|
|
|
|
fence.endpoints.insert(*endpoint);
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-08-22 17:16:56 +00:00
|
|
|
let authority_epoch = store.advance_authority_epoch()?;
|
|
|
|
|
Ok(Self {
|
|
|
|
|
store,
|
|
|
|
|
sources,
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
streams: BTreeMap::new(),
|
2026-08-24 15:22:20 +00:00
|
|
|
blob_reservations: BTreeMap::new(),
|
2026-08-27 22:09:26 +00:00
|
|
|
pending_retirements,
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
pending_stream_displacements,
|
|
|
|
|
stream_replacement_fences,
|
2026-08-22 17:16:56 +00:00
|
|
|
authority_epoch,
|
2026-08-27 22:09:26 +00:00
|
|
|
retire_retry,
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
retirement_watches: HashMap::new(),
|
|
|
|
|
retirement_retry_queue,
|
|
|
|
|
retirement_timer: None,
|
|
|
|
|
#[cfg(feature = "directory-trace")]
|
|
|
|
|
trace: DirectoryTrace::new(),
|
2026-08-22 17:16:56 +00:00
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
fn watch_retirement(&mut self, ctx: &Ctx<'_>, target: ActorAddress) {
|
|
|
|
|
if self.retirement_watches.contains_key(&target) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
let Some(retry) = &self.retire_retry else {
|
|
|
|
|
return;
|
|
|
|
|
};
|
|
|
|
|
let Some(routes) = &retry.routes else {
|
|
|
|
|
return;
|
|
|
|
|
};
|
|
|
|
|
let sender = retry.sender.clone();
|
|
|
|
|
let directory = ctx.self_addr();
|
|
|
|
|
if let Some(watch) = routes.watch_route(
|
|
|
|
|
target,
|
|
|
|
|
Arc::new(move || {
|
|
|
|
|
let _ = sender.send_to(
|
|
|
|
|
directory,
|
|
|
|
|
DataDirectoryIn::RetirementRouteChanged { target },
|
|
|
|
|
);
|
|
|
|
|
}),
|
|
|
|
|
) {
|
|
|
|
|
self.retirement_watches.insert(target, watch);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn retry_retirement(&mut self, ctx: &Ctx<'_>, target: ActorAddress) {
|
|
|
|
|
if self
|
|
|
|
|
.pending_stream_displacements
|
|
|
|
|
.get(&target)
|
|
|
|
|
.is_some_and(|pending| pending.retry(ctx, target, &mut self.store))
|
|
|
|
|
{
|
|
|
|
|
self.pending_stream_displacements.remove(&target);
|
|
|
|
|
self.retirement_watches.remove(&target);
|
|
|
|
|
}
|
|
|
|
|
self.resume_stream_replacement_fences(ctx);
|
|
|
|
|
let routable = self
|
|
|
|
|
.retire_retry
|
|
|
|
|
.as_ref()
|
|
|
|
|
.and_then(|retry| retry.routes.as_deref())
|
|
|
|
|
.is_none_or(|routes| routes.is_routable(target));
|
|
|
|
|
if routable && self.pending_retirements.contains(&target) {
|
|
|
|
|
let _ = ctx.send(
|
|
|
|
|
target,
|
|
|
|
|
BlobSourceIn::Retire {
|
|
|
|
|
reply_to: Some(ctx.self_addr()),
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-27 22:09:26 +00:00
|
|
|
fn queue_retirement(&mut self, ctx: &Ctx<'_>, source: ActorAddress) {
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
if self.pending_retirements.insert(source) {
|
|
|
|
|
self.retirement_retry_queue.push_back(source);
|
|
|
|
|
}
|
|
|
|
|
self.watch_retirement(ctx, source);
|
2026-08-27 22:09:26 +00:00
|
|
|
let _ = ctx.send(
|
|
|
|
|
source,
|
|
|
|
|
BlobSourceIn::Retire {
|
|
|
|
|
reply_to: Some(ctx.self_addr()),
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
fn retry_retirements(&mut self, ctx: &Ctx<'_>) {
|
|
|
|
|
let store = &mut self.store;
|
|
|
|
|
let watches = &mut self.retirement_watches;
|
|
|
|
|
self.pending_stream_displacements
|
|
|
|
|
.retain(|endpoint, pending| {
|
|
|
|
|
if !pending.retry(ctx, *endpoint, store) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
watches.remove(endpoint);
|
|
|
|
|
false
|
|
|
|
|
});
|
|
|
|
|
let routes = self
|
|
|
|
|
.retire_retry
|
|
|
|
|
.as_ref()
|
|
|
|
|
.and_then(|retry| retry.routes.clone());
|
|
|
|
|
let mut examined = 0;
|
|
|
|
|
let mut sent = 0_u64;
|
|
|
|
|
let pending = self.retirement_retry_queue.len();
|
|
|
|
|
while examined < pending && (sent as usize) < RETIREMENT_RETRY_BATCH {
|
|
|
|
|
let source = self
|
|
|
|
|
.retirement_retry_queue
|
|
|
|
|
.pop_front()
|
|
|
|
|
.expect("pending retry count matches queue");
|
|
|
|
|
examined += 1;
|
|
|
|
|
if !self.pending_retirements.contains(&source) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
self.retirement_retry_queue.push_back(source);
|
|
|
|
|
// Preserve the durable retirement tombstone while a route is
|
|
|
|
|
// absent, but do not flood the actor runtime with frames that
|
|
|
|
|
// cannot be delivered. The route watch re-drives this source as
|
|
|
|
|
// soon as it becomes routable again.
|
|
|
|
|
if routes
|
|
|
|
|
.as_deref()
|
|
|
|
|
.is_some_and(|routes| !routes.is_routable(source))
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2026-08-27 22:09:26 +00:00
|
|
|
let _ = ctx.send(
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
source,
|
2026-08-27 22:09:26 +00:00
|
|
|
BlobSourceIn::Retire {
|
|
|
|
|
reply_to: Some(ctx.self_addr()),
|
|
|
|
|
},
|
|
|
|
|
);
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
sent += 1;
|
|
|
|
|
}
|
|
|
|
|
#[cfg(feature = "directory-trace")]
|
|
|
|
|
{
|
|
|
|
|
self.trace.retire_fans += sent;
|
2026-08-27 22:09:26 +00:00
|
|
|
}
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
self.resume_stream_replacement_fences(ctx);
|
2026-08-27 22:09:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn confirm_retirement(&mut self, source: ActorAddress) -> Result<(), NamespaceError> {
|
|
|
|
|
if !self.pending_retirements.contains(&source) {
|
|
|
|
|
return Ok(());
|
|
|
|
|
}
|
|
|
|
|
let mut next = self.store.snapshot().clone();
|
|
|
|
|
next.retirements.retain(|retired| *retired != source);
|
|
|
|
|
self.store.commit(next)?;
|
|
|
|
|
self.pending_retirements.remove(&source);
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
self.retirement_watches.remove(&source);
|
2026-08-27 22:09:26 +00:00
|
|
|
Ok(())
|
|
|
|
|
}
|
2026-08-22 17:16:56 +00:00
|
|
|
pub fn authority_epoch(&self) -> u64 {
|
|
|
|
|
self.authority_epoch
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn replay(
|
|
|
|
|
&self,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
request: &MutationRequest,
|
|
|
|
|
) -> Option<Result<MutationReceipt, NamespaceError>> {
|
|
|
|
|
self.store
|
|
|
|
|
.snapshot()
|
|
|
|
|
.operations
|
|
|
|
|
.get(&operation_id)
|
|
|
|
|
.map(|operation| {
|
|
|
|
|
if &operation.request != request {
|
|
|
|
|
return Err(NamespaceError::OperationConflict(operation_id));
|
|
|
|
|
}
|
|
|
|
|
match &operation.result {
|
|
|
|
|
PersistedMutationResult::Committed(receipt) => Ok(*receipt),
|
|
|
|
|
PersistedMutationResult::Rejected(MutationRejection::PathNotFound(path)) => {
|
|
|
|
|
Err(NamespaceError::PathNotFound(path.clone()))
|
|
|
|
|
}
|
2026-08-27 22:09:26 +00:00
|
|
|
PersistedMutationResult::Rejected(MutationRejection::PathExists(path)) => {
|
|
|
|
|
Err(NamespaceError::PathExists(path.clone()))
|
|
|
|
|
}
|
|
|
|
|
PersistedMutationResult::Rejected(MutationRejection::StreamActive(path)) => {
|
|
|
|
|
Err(NamespaceError::StreamActive(path.clone()))
|
|
|
|
|
}
|
|
|
|
|
PersistedMutationResult::Rejected(MutationRejection::PathReplaced(path)) => {
|
|
|
|
|
Err(NamespaceError::PathReplaced(path.clone()))
|
|
|
|
|
}
|
2026-08-22 17:16:56 +00:00
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-27 22:09:26 +00:00
|
|
|
/// Persist a rejected mutation under its operation ID so later retries of
|
|
|
|
|
/// the same operation replay the rejection instead of re-evaluating
|
|
|
|
|
/// against state that has since changed. Returns the matching error.
|
|
|
|
|
fn reject(
|
|
|
|
|
&mut self,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
request: MutationRequest,
|
|
|
|
|
rejection: MutationRejection,
|
|
|
|
|
) -> NamespaceError {
|
|
|
|
|
let mut next = self.store.snapshot().clone();
|
|
|
|
|
next.operations.insert(
|
|
|
|
|
operation_id,
|
|
|
|
|
PersistedOperation {
|
|
|
|
|
request,
|
|
|
|
|
result: PersistedMutationResult::Rejected(rejection.clone()),
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
if let Err(error) = self.store.commit(next) {
|
|
|
|
|
return error.into();
|
|
|
|
|
}
|
|
|
|
|
match rejection {
|
|
|
|
|
MutationRejection::PathNotFound(path) => NamespaceError::PathNotFound(path),
|
|
|
|
|
MutationRejection::PathExists(path) => NamespaceError::PathExists(path),
|
|
|
|
|
MutationRejection::StreamActive(path) => NamespaceError::StreamActive(path),
|
|
|
|
|
MutationRejection::PathReplaced(path) => NamespaceError::PathReplaced(path),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn record_stream_participant(
|
|
|
|
|
&mut self,
|
|
|
|
|
path: &DataPath,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
revision: u64,
|
|
|
|
|
) -> Result<(), NamespaceError> {
|
|
|
|
|
let request = MutationRequest::BindStream { path: path.clone() };
|
|
|
|
|
if let Some(existing) = self.store.snapshot().operations.get(&operation_id) {
|
|
|
|
|
return if existing.request == request {
|
|
|
|
|
Ok(())
|
|
|
|
|
} else {
|
|
|
|
|
Err(NamespaceError::OperationConflict(operation_id))
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
let mut next = self.store.snapshot().clone();
|
|
|
|
|
next.operations.insert(
|
|
|
|
|
operation_id,
|
|
|
|
|
PersistedOperation {
|
|
|
|
|
request,
|
|
|
|
|
result: PersistedMutationResult::Committed(MutationReceipt { revision }),
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
self.store.commit(next)?;
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
fn bind_stream(
|
|
|
|
|
&mut self,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
retired: Option<ActorAddress>,
|
|
|
|
|
) -> Result<MutationReceipt, NamespaceError> {
|
|
|
|
|
let request = MutationRequest::BindStream { path: path.clone() };
|
|
|
|
|
if let Some(replayed) = self.replay(operation_id, &request) {
|
|
|
|
|
return replayed;
|
|
|
|
|
}
|
2026-08-27 22:09:26 +00:00
|
|
|
if self.blob_reservations.contains_key(&path) {
|
|
|
|
|
return Err(self.reject(operation_id, request, MutationRejection::PathExists(path)));
|
|
|
|
|
}
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
let revision = self.store.snapshot().next_revision;
|
|
|
|
|
let next_revision = revision
|
|
|
|
|
.checked_add(1)
|
|
|
|
|
.filter(|revision| *revision != 0)
|
|
|
|
|
.ok_or(NamespaceStoreError::RevisionExhausted)?;
|
|
|
|
|
let receipt = MutationReceipt { revision };
|
|
|
|
|
let mut next = self.store.snapshot().clone();
|
|
|
|
|
next.next_revision = next_revision;
|
|
|
|
|
next.bindings.remove(&path);
|
2026-08-24 15:22:20 +00:00
|
|
|
next.stream_nodes.insert(path.clone(), revision);
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
if let Some(retired) = retired
|
|
|
|
|
&& !next.retirements.contains(&retired)
|
|
|
|
|
{
|
|
|
|
|
next.retirements.push(retired);
|
|
|
|
|
}
|
|
|
|
|
next.operations.insert(
|
|
|
|
|
operation_id,
|
|
|
|
|
PersistedOperation {
|
|
|
|
|
request,
|
|
|
|
|
result: PersistedMutationResult::Committed(receipt),
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
self.store.commit(next)?;
|
|
|
|
|
self.sources.remove(&path);
|
|
|
|
|
Ok(receipt)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn send_stream_result(
|
|
|
|
|
&self,
|
|
|
|
|
ctx: &Ctx<'_>,
|
|
|
|
|
request_id: DirectoryRequestId,
|
|
|
|
|
reply_to: ActorAddress,
|
|
|
|
|
result: Result<StreamMatch, NamespaceError>,
|
|
|
|
|
) {
|
|
|
|
|
let _ = ctx.send(
|
|
|
|
|
reply_to,
|
|
|
|
|
NamespaceClientIn::DirectoryReply(DataDirectoryOut::StreamOpened {
|
|
|
|
|
request_id,
|
|
|
|
|
authority_epoch: self.authority_epoch,
|
|
|
|
|
result,
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn displace_stream(&mut self, ctx: &Ctx<'_>, path: &DataPath) {
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
match self.streams.remove(path) {
|
|
|
|
|
Some(RuntimeStream::Pending(pending)) => {
|
|
|
|
|
self.send_stream_result(
|
|
|
|
|
ctx,
|
|
|
|
|
pending.request_id,
|
|
|
|
|
pending.reply_to,
|
|
|
|
|
Err(NamespaceError::PathReplaced(path.clone())),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
Some(RuntimeStream::Active(active)) => {
|
|
|
|
|
// A live generation must be fenced: its endpoints keep a
|
|
|
|
|
// working transport, so removing the runtime entry alone
|
|
|
|
|
// would let displaced writers and readers continue. Fan a
|
|
|
|
|
// displacement notice to both endpoints and keep re-fanning
|
|
|
|
|
// until each acknowledges.
|
|
|
|
|
let incarnation = active.binding.incarnation;
|
|
|
|
|
for endpoint in [active.binding.source, active.binding.sink] {
|
|
|
|
|
if let Err(error) = self.queue_stream_displacement(ctx, endpoint, incarnation) {
|
|
|
|
|
eprintln!("data-directory: persisting stream displacement failed: {error}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
None => {}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn queue_stream_displacement(
|
|
|
|
|
&mut self,
|
|
|
|
|
ctx: &Ctx<'_>,
|
|
|
|
|
endpoint: ActorAddress,
|
|
|
|
|
incarnation: StreamIncarnation,
|
|
|
|
|
) -> Result<(), NamespaceError> {
|
|
|
|
|
if self
|
|
|
|
|
.pending_stream_displacements
|
|
|
|
|
.get(&endpoint)
|
|
|
|
|
.is_some_and(|known| known.incarnation == incarnation)
|
|
|
|
|
{
|
|
|
|
|
return Ok(());
|
|
|
|
|
}
|
|
|
|
|
let mut next = self.store.snapshot().clone();
|
|
|
|
|
next.stream_retirements
|
|
|
|
|
.retain(|(known, _)| *known != endpoint);
|
|
|
|
|
next.stream_retirements.push((endpoint, incarnation));
|
|
|
|
|
self.store.commit(next)?;
|
|
|
|
|
self.pending_stream_displacements.insert(
|
|
|
|
|
endpoint,
|
|
|
|
|
PendingStreamDisplacement {
|
|
|
|
|
incarnation,
|
|
|
|
|
acknowledged: false,
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
self.watch_retirement(ctx, endpoint);
|
|
|
|
|
let _ = ctx.send(
|
|
|
|
|
endpoint,
|
|
|
|
|
HostStreamIn::Displaced {
|
|
|
|
|
incarnation,
|
|
|
|
|
reply_to: Some(ctx.self_addr()),
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn begin_stream_replacement(
|
|
|
|
|
&mut self,
|
|
|
|
|
ctx: &Ctx<'_>,
|
|
|
|
|
request: StreamOpenRequest,
|
|
|
|
|
active: ActiveStream,
|
|
|
|
|
) {
|
|
|
|
|
let path = request.path.clone();
|
|
|
|
|
let incarnation = active.binding.incarnation;
|
|
|
|
|
let endpoints = HashSet::from([active.binding.source, active.binding.sink]);
|
|
|
|
|
let mut next = self.store.snapshot().clone();
|
|
|
|
|
for endpoint in &endpoints {
|
|
|
|
|
next.stream_retirements
|
|
|
|
|
.retain(|(known, _)| known != endpoint);
|
|
|
|
|
next.stream_retirements.push((*endpoint, incarnation));
|
|
|
|
|
}
|
|
|
|
|
if let Err(error) = self.store.commit(next) {
|
|
|
|
|
self.streams.insert(path, RuntimeStream::Active(active));
|
|
|
|
|
self.send_stream_result(ctx, request.request_id, request.reply_to, Err(error.into()));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
for endpoint in &endpoints {
|
|
|
|
|
self.pending_stream_displacements.insert(
|
|
|
|
|
*endpoint,
|
|
|
|
|
PendingStreamDisplacement {
|
|
|
|
|
incarnation,
|
|
|
|
|
acknowledged: false,
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
self.watch_retirement(ctx, *endpoint);
|
|
|
|
|
}
|
|
|
|
|
self.stream_replacement_fences.insert(
|
|
|
|
|
path,
|
|
|
|
|
StreamReplacementFence {
|
|
|
|
|
incarnation,
|
|
|
|
|
endpoints: endpoints.clone(),
|
|
|
|
|
old: Some(active),
|
|
|
|
|
requests: vec![request],
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
for endpoint in endpoints {
|
|
|
|
|
let _ = ctx.send(
|
|
|
|
|
endpoint,
|
|
|
|
|
HostStreamIn::Displaced {
|
|
|
|
|
incarnation,
|
|
|
|
|
reply_to: Some(ctx.self_addr()),
|
|
|
|
|
},
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
fn resume_stream_replacement_fences(&mut self, ctx: &Ctx<'_>) {
|
|
|
|
|
let ready: Vec<_> = self
|
|
|
|
|
.stream_replacement_fences
|
|
|
|
|
.iter()
|
|
|
|
|
.filter(|(_, fence)| {
|
|
|
|
|
fence.endpoints.iter().all(|endpoint| {
|
|
|
|
|
self.pending_stream_displacements
|
|
|
|
|
.get(endpoint)
|
|
|
|
|
.is_none_or(|pending| pending.incarnation != fence.incarnation)
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
.map(|(path, _)| path.clone())
|
|
|
|
|
.collect();
|
|
|
|
|
for path in ready {
|
|
|
|
|
if let Some(fence) = self.stream_replacement_fences.remove(&path) {
|
|
|
|
|
for request in fence.requests {
|
|
|
|
|
self.open_stream(ctx, request);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn hold_stream_open_for_fence(&mut self, ctx: &Ctx<'_>, request: StreamOpenRequest) {
|
|
|
|
|
let old_reply = self
|
|
|
|
|
.stream_replacement_fences
|
|
|
|
|
.get(&request.path)
|
|
|
|
|
.and_then(|fence| fence.old.as_ref())
|
|
|
|
|
.and_then(|old| {
|
|
|
|
|
let belongs_to_old = request.operation_id == old.source_operation
|
|
|
|
|
|| request.operation_id == old.sink_operation;
|
|
|
|
|
belongs_to_old.then(|| {
|
|
|
|
|
let expected = match request.role {
|
|
|
|
|
StreamRole::Source => (old.source_operation, old.binding.source),
|
|
|
|
|
StreamRole::Sink => (old.sink_operation, old.binding.sink),
|
|
|
|
|
};
|
|
|
|
|
if expected == (request.operation_id, request.endpoint) {
|
|
|
|
|
Ok(old.binding.clone())
|
|
|
|
|
} else {
|
|
|
|
|
Err(NamespaceError::OperationConflict(request.operation_id))
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
if let Some(result) = old_reply {
|
|
|
|
|
self.send_stream_result(ctx, request.request_id, request.reply_to, result);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
let fence = self
|
|
|
|
|
.stream_replacement_fences
|
|
|
|
|
.get_mut(&request.path)
|
|
|
|
|
.expect("replacement fence checked");
|
|
|
|
|
if let Some(known) = fence.requests.iter_mut().find(|known| {
|
|
|
|
|
known.operation_id == request.operation_id
|
|
|
|
|
&& known.role == request.role
|
|
|
|
|
&& known.endpoint == request.endpoint
|
|
|
|
|
}) {
|
|
|
|
|
*known = request;
|
|
|
|
|
} else {
|
|
|
|
|
fence.requests.push(request);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn confirm_stream_displacement(
|
|
|
|
|
&mut self,
|
|
|
|
|
ctx: &Ctx<'_>,
|
|
|
|
|
endpoint: ActorAddress,
|
|
|
|
|
incarnation: StreamIncarnation,
|
|
|
|
|
) {
|
|
|
|
|
let Some(pending) = self.pending_stream_displacements.get_mut(&endpoint) else {
|
|
|
|
|
return;
|
|
|
|
|
};
|
|
|
|
|
if pending.incarnation != incarnation {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
pending.acknowledged = true;
|
|
|
|
|
self.retry_retirement(ctx, endpoint);
|
|
|
|
|
}
|
|
|
|
|
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
fn open_stream(&mut self, ctx: &Ctx<'_>, request: StreamOpenRequest) {
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
if self.stream_replacement_fences.contains_key(&request.path) {
|
|
|
|
|
self.hold_stream_open_for_fence(ctx, request);
|
|
|
|
|
return;
|
|
|
|
|
}
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
let StreamOpenRequest {
|
|
|
|
|
request_id,
|
|
|
|
|
path,
|
|
|
|
|
role,
|
|
|
|
|
endpoint,
|
|
|
|
|
replace,
|
2026-08-24 15:22:20 +00:00
|
|
|
ensure,
|
|
|
|
|
expected_revision,
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
descriptor,
|
|
|
|
|
operation_id,
|
|
|
|
|
reply_to,
|
|
|
|
|
} = request;
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
if let Some(replayed) = self.replay(
|
2026-08-27 22:09:26 +00:00
|
|
|
operation_id,
|
|
|
|
|
&MutationRequest::BindStream { path: path.clone() },
|
|
|
|
|
) {
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
let receipt = match replayed {
|
|
|
|
|
// A cancelled open replays its persisted rejection: the
|
|
|
|
|
// cancel tombstone must win over a reordered late retry.
|
|
|
|
|
Err(error) => {
|
|
|
|
|
self.send_stream_result(ctx, request_id, reply_to, Err(error));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
Ok(receipt) => receipt,
|
|
|
|
|
};
|
2026-08-27 22:09:26 +00:00
|
|
|
let is_current = matches!(
|
|
|
|
|
self.streams.get(&path),
|
|
|
|
|
Some(RuntimeStream::Pending(pending))
|
|
|
|
|
if pending.operation_id == operation_id
|
|
|
|
|
) || matches!(
|
|
|
|
|
self.streams.get(&path),
|
|
|
|
|
Some(RuntimeStream::Active(active))
|
|
|
|
|
if active.source_operation == operation_id
|
|
|
|
|
|| active.sink_operation == operation_id
|
|
|
|
|
);
|
|
|
|
|
if !is_current {
|
|
|
|
|
self.send_stream_result(
|
|
|
|
|
ctx,
|
|
|
|
|
request_id,
|
|
|
|
|
reply_to,
|
|
|
|
|
Err(NamespaceError::StaleIncarnation {
|
|
|
|
|
path,
|
|
|
|
|
incarnation: StreamIncarnation {
|
|
|
|
|
authority_epoch: self.authority_epoch,
|
|
|
|
|
revision: receipt.revision,
|
|
|
|
|
},
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-08-24 15:22:20 +00:00
|
|
|
if !ensure {
|
|
|
|
|
let snapshot = self.store.snapshot();
|
|
|
|
|
let Some(current_revision) = snapshot.stream_nodes.get(&path).copied() else {
|
|
|
|
|
let error = if snapshot.bindings.contains_key(&path) {
|
|
|
|
|
NamespaceError::WrongEntryType {
|
|
|
|
|
path,
|
|
|
|
|
expected: EntryKind::Stream,
|
|
|
|
|
found: EntryKind::Blob,
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
NamespaceError::PathNotFound(path)
|
|
|
|
|
};
|
|
|
|
|
self.send_stream_result(ctx, request_id, reply_to, Err(error));
|
|
|
|
|
return;
|
|
|
|
|
};
|
|
|
|
|
let pending_from_expected = matches!(
|
|
|
|
|
self.streams.get(&path),
|
|
|
|
|
Some(RuntimeStream::Pending(pending))
|
|
|
|
|
if pending.opened_from_revision == expected_revision
|
|
|
|
|
);
|
|
|
|
|
if expected_revision != Some(current_revision) && !pending_from_expected {
|
|
|
|
|
self.send_stream_result(
|
|
|
|
|
ctx,
|
|
|
|
|
request_id,
|
|
|
|
|
reply_to,
|
|
|
|
|
Err(NamespaceError::PathReplaced(path)),
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
if let Some(RuntimeStream::Pending(pending)) = self.streams.get_mut(&path)
|
|
|
|
|
&& pending.operation_id == operation_id
|
|
|
|
|
{
|
|
|
|
|
if pending.role != role || pending.endpoint != endpoint {
|
|
|
|
|
self.send_stream_result(
|
|
|
|
|
ctx,
|
|
|
|
|
request_id,
|
|
|
|
|
reply_to,
|
|
|
|
|
Err(NamespaceError::OperationConflict(operation_id)),
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
pending.request_id = request_id;
|
|
|
|
|
pending.reply_to = reply_to;
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if let Some(RuntimeStream::Active(active)) = self.streams.get(&path)
|
|
|
|
|
&& (active.source_operation == operation_id || active.sink_operation == operation_id)
|
|
|
|
|
{
|
|
|
|
|
self.send_stream_result(ctx, request_id, reply_to, Ok(active.binding.clone()));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
if replace && matches!(self.streams.get(&path), Some(RuntimeStream::Active(_))) {
|
|
|
|
|
let Some(RuntimeStream::Active(active)) = self.streams.remove(&path) else {
|
|
|
|
|
unreachable!("active stream checked");
|
|
|
|
|
};
|
|
|
|
|
self.begin_stream_replacement(
|
|
|
|
|
ctx,
|
|
|
|
|
StreamOpenRequest {
|
|
|
|
|
request_id,
|
|
|
|
|
path,
|
|
|
|
|
role,
|
|
|
|
|
endpoint,
|
|
|
|
|
replace,
|
|
|
|
|
ensure,
|
|
|
|
|
expected_revision,
|
|
|
|
|
descriptor,
|
|
|
|
|
operation_id,
|
|
|
|
|
reply_to,
|
|
|
|
|
},
|
|
|
|
|
active,
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
}
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
let compatible_pending = matches!(
|
|
|
|
|
self.streams.get(&path),
|
|
|
|
|
Some(RuntimeStream::Pending(pending)) if pending.role != role
|
|
|
|
|
);
|
|
|
|
|
if replace && self.streams.contains_key(&path) && !compatible_pending {
|
|
|
|
|
self.displace_stream(ctx, &path);
|
|
|
|
|
}
|
|
|
|
|
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
if matches!(self.streams.get(&path), Some(RuntimeStream::Pending(_))) {
|
|
|
|
|
let Some(RuntimeStream::Pending(pending)) = self.streams.remove(&path) else {
|
|
|
|
|
unreachable!("pending stream checked");
|
|
|
|
|
};
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
if pending.role == role {
|
|
|
|
|
self.streams
|
|
|
|
|
.insert(path.clone(), RuntimeStream::Pending(pending));
|
|
|
|
|
self.send_stream_result(
|
|
|
|
|
ctx,
|
|
|
|
|
request_id,
|
|
|
|
|
reply_to,
|
|
|
|
|
Err(NamespaceError::DuplicateStreamRole { path, role }),
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-08-27 22:09:26 +00:00
|
|
|
if let Err(error) =
|
|
|
|
|
self.record_stream_participant(&path, operation_id, pending.revision)
|
|
|
|
|
{
|
|
|
|
|
self.streams
|
|
|
|
|
.insert(path.clone(), RuntimeStream::Pending(pending));
|
|
|
|
|
self.send_stream_result(ctx, request_id, reply_to, Err(error));
|
|
|
|
|
return;
|
|
|
|
|
}
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
let (
|
|
|
|
|
source,
|
|
|
|
|
sink,
|
|
|
|
|
source_descriptor,
|
|
|
|
|
sink_descriptor,
|
|
|
|
|
source_operation,
|
|
|
|
|
sink_operation,
|
|
|
|
|
) = match role {
|
|
|
|
|
StreamRole::Source => (
|
|
|
|
|
endpoint,
|
|
|
|
|
pending.endpoint,
|
|
|
|
|
descriptor,
|
|
|
|
|
pending.descriptor,
|
|
|
|
|
operation_id,
|
|
|
|
|
pending.operation_id,
|
|
|
|
|
),
|
|
|
|
|
StreamRole::Sink => (
|
|
|
|
|
pending.endpoint,
|
|
|
|
|
endpoint,
|
|
|
|
|
pending.descriptor,
|
|
|
|
|
descriptor,
|
|
|
|
|
pending.operation_id,
|
|
|
|
|
operation_id,
|
|
|
|
|
),
|
|
|
|
|
};
|
|
|
|
|
let binding = StreamMatch {
|
|
|
|
|
incarnation: StreamIncarnation {
|
|
|
|
|
authority_epoch: self.authority_epoch,
|
|
|
|
|
revision: pending.revision,
|
|
|
|
|
},
|
|
|
|
|
source,
|
|
|
|
|
source_descriptor,
|
|
|
|
|
sink_descriptor,
|
|
|
|
|
sink,
|
|
|
|
|
revision: pending.revision,
|
|
|
|
|
};
|
|
|
|
|
self.send_stream_result(
|
|
|
|
|
ctx,
|
|
|
|
|
pending.request_id,
|
|
|
|
|
pending.reply_to,
|
|
|
|
|
Ok(binding.clone()),
|
|
|
|
|
);
|
|
|
|
|
self.send_stream_result(ctx, request_id, reply_to, Ok(binding.clone()));
|
|
|
|
|
self.streams.insert(
|
|
|
|
|
path,
|
|
|
|
|
RuntimeStream::Active(ActiveStream {
|
|
|
|
|
binding,
|
|
|
|
|
source_operation,
|
|
|
|
|
sink_operation,
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if self.streams.contains_key(&path) {
|
|
|
|
|
self.send_stream_result(
|
|
|
|
|
ctx,
|
|
|
|
|
request_id,
|
|
|
|
|
reply_to,
|
|
|
|
|
Err(NamespaceError::DuplicateStreamRole { path, role }),
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if self.store.snapshot().bindings.contains_key(&path) && !replace {
|
|
|
|
|
self.send_stream_result(
|
|
|
|
|
ctx,
|
|
|
|
|
request_id,
|
|
|
|
|
reply_to,
|
|
|
|
|
Err(NamespaceError::WrongEntryType {
|
|
|
|
|
path,
|
|
|
|
|
expected: EntryKind::Stream,
|
|
|
|
|
found: EntryKind::Blob,
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
let retired = self.sources.get(&path).and_then(|source| match source {
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
RuntimeSource::Available { actor, .. } => Some(*actor),
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
RuntimeSource::Unavailable(_) => None,
|
|
|
|
|
});
|
|
|
|
|
match self.bind_stream(path.clone(), operation_id, retired) {
|
|
|
|
|
Ok(receipt) => {
|
|
|
|
|
if let Some(retired) = retired {
|
2026-08-27 22:09:26 +00:00
|
|
|
self.queue_retirement(ctx, retired);
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
}
|
|
|
|
|
self.streams.insert(
|
|
|
|
|
path,
|
|
|
|
|
RuntimeStream::Pending(PendingStream {
|
|
|
|
|
role,
|
|
|
|
|
descriptor,
|
|
|
|
|
endpoint,
|
|
|
|
|
operation_id,
|
|
|
|
|
request_id,
|
|
|
|
|
reply_to,
|
|
|
|
|
revision: receipt.revision,
|
2026-08-24 15:22:20 +00:00
|
|
|
opened_from_revision: (!ensure).then_some(expected_revision).flatten(),
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
Err(error) => self.send_stream_result(ctx, request_id, reply_to, Err(error)),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
/// Retract a waiting stream open. Cancels ride the same at-most-once
|
|
|
|
|
/// transport as every other directory frame, so callers re-send them
|
|
|
|
|
/// until acknowledged, and the cancel must also survive reordering
|
|
|
|
|
/// against the open itself: when the open frame was lost and lands only
|
|
|
|
|
/// after this cancel, the persisted rejection below turns its replay
|
|
|
|
|
/// into a typed failure instead of resurrecting a pending endpoint that
|
|
|
|
|
/// no live actor will ever close.
|
|
|
|
|
fn cancel_stream(
|
|
|
|
|
&mut self,
|
|
|
|
|
path: &DataPath,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
) -> Result<(), NamespaceError> {
|
|
|
|
|
if !self.store.snapshot().operations.contains_key(&operation_id) {
|
|
|
|
|
let request = MutationRequest::BindStream { path: path.clone() };
|
|
|
|
|
let mut next = self.store.snapshot().clone();
|
|
|
|
|
next.operations.insert(
|
|
|
|
|
operation_id,
|
|
|
|
|
PersistedOperation {
|
|
|
|
|
request,
|
|
|
|
|
result: PersistedMutationResult::Rejected(MutationRejection::PathReplaced(
|
|
|
|
|
path.clone(),
|
|
|
|
|
)),
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
self.store.commit(next)?;
|
|
|
|
|
}
|
|
|
|
|
if matches!(
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
self.streams.get(path),
|
|
|
|
|
Some(RuntimeStream::Pending(pending)) if pending.operation_id == operation_id
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
) {
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
self.streams.remove(path);
|
|
|
|
|
}
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
if let Some(fence) = self.stream_replacement_fences.get_mut(path) {
|
|
|
|
|
fence
|
|
|
|
|
.requests
|
|
|
|
|
.retain(|request| request.operation_id != operation_id);
|
|
|
|
|
}
|
|
|
|
|
Ok(())
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn close_stream(
|
|
|
|
|
&mut self,
|
|
|
|
|
path: &DataPath,
|
|
|
|
|
incarnation: StreamIncarnation,
|
|
|
|
|
) -> Result<(), NamespaceError> {
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
let active_matches = matches!(
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
self.streams.get(path),
|
|
|
|
|
Some(RuntimeStream::Active(active)) if active.binding.incarnation == incarnation
|
|
|
|
|
);
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
if active_matches {
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
self.streams.remove(path);
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
return Ok(());
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
}
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
let already_closed = !self.streams.contains_key(path)
|
|
|
|
|
&& incarnation.authority_epoch == self.authority_epoch
|
|
|
|
|
&& self.store.snapshot().stream_nodes.get(path).copied() == Some(incarnation.revision);
|
|
|
|
|
if already_closed {
|
|
|
|
|
return Ok(());
|
|
|
|
|
}
|
|
|
|
|
Err(NamespaceError::StaleIncarnation {
|
|
|
|
|
path: path.clone(),
|
|
|
|
|
incarnation,
|
|
|
|
|
})
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
}
|
|
|
|
|
|
2026-08-24 15:22:20 +00:00
|
|
|
fn reserve_blob(
|
|
|
|
|
&mut self,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
) -> Result<(), NamespaceError> {
|
|
|
|
|
if self.store.snapshot().bindings.contains_key(&path)
|
|
|
|
|
|| self.store.snapshot().stream_nodes.contains_key(&path)
|
|
|
|
|
{
|
|
|
|
|
return Err(NamespaceError::PathExists(path));
|
|
|
|
|
}
|
|
|
|
|
match self.blob_reservations.get(&path) {
|
|
|
|
|
Some(existing) if *existing == operation_id => Ok(()),
|
|
|
|
|
Some(_) => Err(NamespaceError::PathExists(path)),
|
|
|
|
|
None => {
|
|
|
|
|
self.blob_reservations.insert(path, operation_id);
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn release_blob_reservation(
|
|
|
|
|
&mut self,
|
|
|
|
|
path: &DataPath,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
) -> Result<(), NamespaceError> {
|
|
|
|
|
match self.blob_reservations.get(path) {
|
|
|
|
|
Some(existing) if *existing == operation_id => {
|
|
|
|
|
self.blob_reservations.remove(path);
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
Some(_) => Err(NamespaceError::OperationConflict(operation_id)),
|
|
|
|
|
None => Ok(()),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-22 17:16:56 +00:00
|
|
|
fn register(
|
|
|
|
|
&mut self,
|
2026-08-27 22:09:26 +00:00
|
|
|
registration: BlobRegistration,
|
2026-08-22 17:16:56 +00:00
|
|
|
) -> Result<MutationReceipt, NamespaceError> {
|
2026-08-27 22:09:26 +00:00
|
|
|
let BlobRegistration {
|
|
|
|
|
path,
|
|
|
|
|
source,
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
source_node,
|
2026-08-27 22:09:26 +00:00
|
|
|
length,
|
|
|
|
|
recovery,
|
|
|
|
|
operation_id,
|
|
|
|
|
reservation,
|
|
|
|
|
retired,
|
|
|
|
|
} = registration;
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
let owner = match &recovery {
|
|
|
|
|
SourceRecovery::Actor { owner, .. } => *owner,
|
|
|
|
|
SourceRecovery::File { .. } => None,
|
|
|
|
|
};
|
2026-08-22 17:16:56 +00:00
|
|
|
let request = MutationRequest::Register {
|
|
|
|
|
path: path.clone(),
|
|
|
|
|
length,
|
|
|
|
|
recovery: recovery.clone(),
|
|
|
|
|
};
|
|
|
|
|
if let Some(replayed) = self.replay(operation_id, &request) {
|
|
|
|
|
return replayed;
|
|
|
|
|
}
|
2026-08-24 15:22:20 +00:00
|
|
|
match self.blob_reservations.get(&path) {
|
|
|
|
|
Some(existing) if Some(*existing) == reservation => {}
|
2026-08-27 22:09:26 +00:00
|
|
|
Some(_) => {
|
|
|
|
|
return Err(self.reject(
|
|
|
|
|
operation_id,
|
|
|
|
|
request,
|
|
|
|
|
MutationRejection::PathExists(path),
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
None if reservation.is_some() => {
|
|
|
|
|
return Err(self.reject(
|
|
|
|
|
operation_id,
|
|
|
|
|
request,
|
|
|
|
|
MutationRejection::PathReplaced(path),
|
|
|
|
|
));
|
|
|
|
|
}
|
2026-08-24 15:22:20 +00:00
|
|
|
None => {}
|
|
|
|
|
}
|
2026-08-22 17:16:56 +00:00
|
|
|
let revision = self.store.snapshot().next_revision;
|
|
|
|
|
let next_revision = revision
|
|
|
|
|
.checked_add(1)
|
|
|
|
|
.filter(|revision| *revision != 0)
|
|
|
|
|
.ok_or(NamespaceStoreError::RevisionExhausted)?;
|
|
|
|
|
let receipt = MutationReceipt { revision };
|
|
|
|
|
let mut next = self.store.snapshot().clone();
|
|
|
|
|
next.next_revision = next_revision;
|
2026-08-24 15:22:20 +00:00
|
|
|
next.stream_nodes.remove(&path);
|
2026-08-22 17:16:56 +00:00
|
|
|
next.bindings.insert(
|
|
|
|
|
path.clone(),
|
|
|
|
|
PersistedBinding {
|
|
|
|
|
length,
|
|
|
|
|
revision,
|
|
|
|
|
recovery,
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
if let Some(retired) = retired
|
|
|
|
|
&& !next.retirements.contains(&retired)
|
|
|
|
|
{
|
|
|
|
|
next.retirements.push(retired);
|
|
|
|
|
}
|
|
|
|
|
next.operations.insert(
|
|
|
|
|
operation_id,
|
|
|
|
|
PersistedOperation {
|
|
|
|
|
request,
|
|
|
|
|
result: PersistedMutationResult::Committed(receipt),
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
self.store.commit(next)?;
|
2026-08-24 15:22:20 +00:00
|
|
|
if reservation.is_some() {
|
|
|
|
|
self.blob_reservations.remove(&path);
|
|
|
|
|
}
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
self.sources.insert(
|
|
|
|
|
path,
|
|
|
|
|
RuntimeSource::Available {
|
|
|
|
|
actor: source,
|
|
|
|
|
node: source_node,
|
|
|
|
|
owner,
|
|
|
|
|
},
|
|
|
|
|
);
|
2026-08-22 17:16:56 +00:00
|
|
|
Ok(receipt)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn resolve(&self, path: &DataPath) -> Result<BlobBinding, NamespaceError> {
|
2026-08-24 15:22:20 +00:00
|
|
|
if self.store.snapshot().stream_nodes.contains_key(path) {
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
return Err(NamespaceError::WrongEntryType {
|
|
|
|
|
path: path.clone(),
|
|
|
|
|
expected: EntryKind::Blob,
|
|
|
|
|
found: EntryKind::Stream,
|
|
|
|
|
});
|
|
|
|
|
}
|
2026-08-22 17:16:56 +00:00
|
|
|
let persisted = self
|
|
|
|
|
.store
|
|
|
|
|
.snapshot()
|
|
|
|
|
.bindings
|
|
|
|
|
.get(path)
|
|
|
|
|
.ok_or_else(|| NamespaceError::PathNotFound(path.clone()))?;
|
|
|
|
|
match self.sources.get(path) {
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
Some(RuntimeSource::Available { actor, node, owner }) => Ok(BlobBinding {
|
|
|
|
|
source: *actor,
|
|
|
|
|
source_node: *node,
|
|
|
|
|
owner: *owner,
|
2026-08-22 17:16:56 +00:00
|
|
|
length: persisted.length,
|
|
|
|
|
revision: persisted.revision,
|
|
|
|
|
}),
|
|
|
|
|
Some(RuntimeSource::Unavailable(reason)) => {
|
|
|
|
|
Err(NamespaceError::SourceRecovery(reason.clone()))
|
|
|
|
|
}
|
|
|
|
|
None => Err(NamespaceError::SourceRecovery(format!(
|
|
|
|
|
"binding {path} has no recovered runtime source"
|
|
|
|
|
))),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-24 15:22:20 +00:00
|
|
|
fn lookup(&self, path: &DataPath) -> Result<NamespaceNode, NamespaceError> {
|
|
|
|
|
if self.blob_reservations.contains_key(path) {
|
|
|
|
|
return Err(NamespaceError::PathExists(path.clone()));
|
|
|
|
|
}
|
|
|
|
|
let snapshot = self.store.snapshot();
|
|
|
|
|
match (snapshot.bindings.get(path), snapshot.stream_nodes.get(path)) {
|
|
|
|
|
(Some(binding), None) => Ok(NamespaceNode {
|
|
|
|
|
kind: EntryKind::Blob,
|
|
|
|
|
revision: binding.revision,
|
2026-08-27 22:09:26 +00:00
|
|
|
active: false,
|
2026-08-24 15:22:20 +00:00
|
|
|
}),
|
|
|
|
|
(None, Some(revision)) => Ok(NamespaceNode {
|
|
|
|
|
kind: EntryKind::Stream,
|
|
|
|
|
revision: *revision,
|
2026-08-27 22:09:26 +00:00
|
|
|
active: self.streams.contains_key(path),
|
2026-08-24 15:22:20 +00:00
|
|
|
}),
|
|
|
|
|
(None, None) => Err(NamespaceError::PathNotFound(path.clone())),
|
|
|
|
|
(Some(_), Some(_)) => Err(NamespaceError::Storage(format!(
|
|
|
|
|
"data path {path} is bound as both blob and stream"
|
|
|
|
|
))),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-22 17:16:56 +00:00
|
|
|
fn unregister(
|
|
|
|
|
&mut self,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
retired: Option<ActorAddress>,
|
|
|
|
|
) -> Result<MutationReceipt, NamespaceError> {
|
|
|
|
|
let request = MutationRequest::Unregister { path: path.clone() };
|
|
|
|
|
if let Some(replayed) = self.replay(operation_id, &request) {
|
|
|
|
|
return replayed;
|
|
|
|
|
}
|
2026-08-27 22:09:26 +00:00
|
|
|
if self.blob_reservations.contains_key(&path) {
|
|
|
|
|
return Err(self.reject(operation_id, request, MutationRejection::PathExists(path)));
|
|
|
|
|
}
|
2026-08-24 15:22:20 +00:00
|
|
|
if !self.store.snapshot().bindings.contains_key(&path)
|
|
|
|
|
&& !self.store.snapshot().stream_nodes.contains_key(&path)
|
|
|
|
|
{
|
2026-08-27 22:09:26 +00:00
|
|
|
return Err(self.reject(operation_id, request, MutationRejection::PathNotFound(path)));
|
2026-08-22 17:16:56 +00:00
|
|
|
}
|
|
|
|
|
let revision = self.store.snapshot().next_revision;
|
|
|
|
|
let next_revision = revision
|
|
|
|
|
.checked_add(1)
|
|
|
|
|
.filter(|revision| *revision != 0)
|
|
|
|
|
.ok_or(NamespaceStoreError::RevisionExhausted)?;
|
|
|
|
|
let receipt = MutationReceipt { revision };
|
|
|
|
|
let mut next = self.store.snapshot().clone();
|
|
|
|
|
next.next_revision = next_revision;
|
|
|
|
|
next.bindings.remove(&path);
|
2026-08-24 15:22:20 +00:00
|
|
|
next.stream_nodes.remove(&path);
|
2026-08-22 17:16:56 +00:00
|
|
|
if let Some(retired) = retired
|
|
|
|
|
&& !next.retirements.contains(&retired)
|
|
|
|
|
{
|
|
|
|
|
next.retirements.push(retired);
|
|
|
|
|
}
|
|
|
|
|
next.operations.insert(
|
|
|
|
|
operation_id,
|
|
|
|
|
PersistedOperation {
|
|
|
|
|
request,
|
|
|
|
|
result: PersistedMutationResult::Committed(receipt),
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
self.store.commit(next)?;
|
|
|
|
|
self.sources.remove(&path);
|
|
|
|
|
Ok(receipt)
|
|
|
|
|
}
|
2026-08-27 22:09:26 +00:00
|
|
|
|
|
|
|
|
fn rename(
|
|
|
|
|
&mut self,
|
|
|
|
|
source: DataPath,
|
|
|
|
|
destination: DataPath,
|
|
|
|
|
replace: bool,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
) -> Result<MutationReceipt, NamespaceError> {
|
|
|
|
|
let request = MutationRequest::Rename {
|
|
|
|
|
source: source.clone(),
|
|
|
|
|
destination: destination.clone(),
|
|
|
|
|
replace,
|
|
|
|
|
};
|
|
|
|
|
if let Some(replayed) = self.replay(operation_id, &request) {
|
|
|
|
|
return replayed;
|
|
|
|
|
}
|
|
|
|
|
let snapshot = self.store.snapshot();
|
|
|
|
|
let source_exists =
|
|
|
|
|
snapshot.bindings.contains_key(&source) || snapshot.stream_nodes.contains_key(&source);
|
|
|
|
|
if !source_exists {
|
|
|
|
|
return Err(self.reject(
|
|
|
|
|
operation_id,
|
|
|
|
|
request,
|
|
|
|
|
MutationRejection::PathNotFound(source),
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
if self.blob_reservations.contains_key(&source)
|
|
|
|
|
|| self.blob_reservations.contains_key(&destination)
|
|
|
|
|
{
|
|
|
|
|
let reserved = if self.blob_reservations.contains_key(&source) {
|
|
|
|
|
source
|
|
|
|
|
} else {
|
|
|
|
|
destination
|
|
|
|
|
};
|
|
|
|
|
return Err(self.reject(
|
|
|
|
|
operation_id,
|
|
|
|
|
request,
|
|
|
|
|
MutationRejection::PathExists(reserved),
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
let active_path = self
|
|
|
|
|
.streams
|
|
|
|
|
.contains_key(&source)
|
|
|
|
|
.then_some(source.clone())
|
|
|
|
|
.or_else(|| {
|
|
|
|
|
self.streams
|
|
|
|
|
.contains_key(&destination)
|
|
|
|
|
.then_some(destination.clone())
|
|
|
|
|
});
|
|
|
|
|
if let Some(path) = active_path {
|
|
|
|
|
return Err(self.reject(operation_id, request, MutationRejection::StreamActive(path)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let destination_exists = snapshot.bindings.contains_key(&destination)
|
|
|
|
|
|| snapshot.stream_nodes.contains_key(&destination);
|
|
|
|
|
if source != destination && destination_exists && !replace {
|
|
|
|
|
return Err(self.reject(
|
|
|
|
|
operation_id,
|
|
|
|
|
request,
|
|
|
|
|
MutationRejection::PathExists(destination),
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let revision = snapshot.next_revision;
|
|
|
|
|
let next_revision = revision
|
|
|
|
|
.checked_add(1)
|
|
|
|
|
.filter(|revision| *revision != 0)
|
|
|
|
|
.ok_or(NamespaceStoreError::RevisionExhausted)?;
|
|
|
|
|
let receipt = MutationReceipt { revision };
|
|
|
|
|
let destination_retired = (source != destination)
|
|
|
|
|
.then(|| self.sources.get(&destination))
|
|
|
|
|
.flatten()
|
|
|
|
|
.and_then(|source| match source {
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
RuntimeSource::Available { actor, .. } => Some(*actor),
|
2026-08-27 22:09:26 +00:00
|
|
|
RuntimeSource::Unavailable(_) => None,
|
|
|
|
|
});
|
|
|
|
|
let mut next = snapshot.clone();
|
|
|
|
|
next.next_revision = next_revision;
|
|
|
|
|
let source_binding = next.bindings.remove(&source);
|
|
|
|
|
let source_stream = next.stream_nodes.remove(&source);
|
|
|
|
|
next.bindings.remove(&destination);
|
|
|
|
|
next.stream_nodes.remove(&destination);
|
|
|
|
|
if let Some(mut binding) = source_binding {
|
|
|
|
|
binding.revision = revision;
|
|
|
|
|
next.bindings.insert(destination.clone(), binding);
|
|
|
|
|
} else if source_stream.is_some() {
|
|
|
|
|
next.stream_nodes.insert(destination.clone(), revision);
|
|
|
|
|
}
|
|
|
|
|
if let Some(retired) = destination_retired
|
|
|
|
|
&& !next.retirements.contains(&retired)
|
|
|
|
|
{
|
|
|
|
|
next.retirements.push(retired);
|
|
|
|
|
}
|
|
|
|
|
next.operations.insert(
|
|
|
|
|
operation_id,
|
|
|
|
|
PersistedOperation {
|
|
|
|
|
request,
|
|
|
|
|
result: PersistedMutationResult::Committed(receipt),
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
self.store.commit(next)?;
|
|
|
|
|
|
|
|
|
|
let source_runtime = self.sources.remove(&source);
|
|
|
|
|
if source != destination {
|
|
|
|
|
self.sources.remove(&destination);
|
|
|
|
|
}
|
|
|
|
|
if let Some(source_runtime) = source_runtime {
|
|
|
|
|
self.sources.insert(destination, source_runtime);
|
|
|
|
|
}
|
|
|
|
|
Ok(receipt)
|
|
|
|
|
}
|
2026-08-22 17:16:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl ActorInterface for DataDirectoryActor {
|
|
|
|
|
type Incoming = DataDirectoryIn;
|
|
|
|
|
type Response = ();
|
|
|
|
|
|
|
|
|
|
fn on_start(&mut self, ctx: &Ctx<'_>) {
|
2026-08-27 22:09:26 +00:00
|
|
|
if let Some(retire_retry) = &self.retire_retry {
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
self.retirement_timer = Some(retire_retry.engine.send_every(
|
2026-08-27 22:09:26 +00:00
|
|
|
retire_retry.period,
|
|
|
|
|
retire_retry.sender.clone(),
|
|
|
|
|
ctx.self_addr(),
|
|
|
|
|
DataDirectoryIn::RetryRetirements,
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
let targets: Vec<_> = self
|
|
|
|
|
.pending_retirements
|
|
|
|
|
.iter()
|
|
|
|
|
.chain(self.pending_stream_displacements.keys())
|
|
|
|
|
.copied()
|
|
|
|
|
.collect();
|
|
|
|
|
for target in targets {
|
|
|
|
|
self.watch_retirement(ctx, target);
|
2026-08-22 17:16:56 +00:00
|
|
|
}
|
2026-08-27 22:09:26 +00:00
|
|
|
self.retry_retirements(ctx);
|
2026-08-22 17:16:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn handle(&mut self, ctx: &Ctx<'_>, message: DataDirectoryIn) {
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
#[cfg(feature = "directory-trace")]
|
|
|
|
|
self.trace
|
|
|
|
|
.observed_step(self.pending_retirements.len(), &self.store);
|
2026-08-22 17:16:56 +00:00
|
|
|
match message {
|
|
|
|
|
DataDirectoryIn::Register {
|
|
|
|
|
request_id,
|
|
|
|
|
path,
|
|
|
|
|
source,
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
source_node,
|
2026-08-22 17:16:56 +00:00
|
|
|
length,
|
|
|
|
|
recovery,
|
|
|
|
|
operation_id,
|
2026-08-24 15:22:20 +00:00
|
|
|
reservation,
|
2026-08-22 17:16:56 +00:00
|
|
|
reply_to,
|
|
|
|
|
} => {
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
let logical = path.clone();
|
2026-08-22 17:16:56 +00:00
|
|
|
let replayed = self.store.snapshot().operations.contains_key(&operation_id);
|
|
|
|
|
let retired = (!replayed)
|
|
|
|
|
.then(|| self.sources.get(&path))
|
|
|
|
|
.flatten()
|
|
|
|
|
.and_then(|runtime_source| match runtime_source {
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
RuntimeSource::Available { actor, .. } if *actor != source => Some(*actor),
|
|
|
|
|
RuntimeSource::Available { .. } | RuntimeSource::Unavailable(_) => None,
|
2026-08-22 17:16:56 +00:00
|
|
|
});
|
2026-08-27 22:09:26 +00:00
|
|
|
let result = self.register(BlobRegistration {
|
2026-08-24 15:22:20 +00:00
|
|
|
path,
|
|
|
|
|
source,
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
source_node,
|
2026-08-24 15:22:20 +00:00
|
|
|
length,
|
|
|
|
|
recovery,
|
|
|
|
|
operation_id,
|
|
|
|
|
reservation,
|
|
|
|
|
retired,
|
2026-08-27 22:09:26 +00:00
|
|
|
});
|
2026-08-22 17:16:56 +00:00
|
|
|
if result.is_ok()
|
|
|
|
|
&& let Some(retired) = retired
|
|
|
|
|
{
|
2026-08-27 22:09:26 +00:00
|
|
|
self.queue_retirement(ctx, retired);
|
2026-08-22 17:16:56 +00:00
|
|
|
}
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
if result.is_ok() {
|
|
|
|
|
self.displace_stream(ctx, &logical);
|
|
|
|
|
}
|
2026-08-22 17:16:56 +00:00
|
|
|
let _ = ctx.send(
|
|
|
|
|
reply_to,
|
|
|
|
|
NamespaceClientIn::DirectoryReply(DataDirectoryOut::Registered {
|
|
|
|
|
request_id,
|
|
|
|
|
authority_epoch: self.authority_epoch,
|
|
|
|
|
result,
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
DataDirectoryIn::Resolve {
|
|
|
|
|
request_id,
|
|
|
|
|
path,
|
|
|
|
|
reply_to,
|
|
|
|
|
} => {
|
|
|
|
|
let result = self.resolve(&path);
|
|
|
|
|
let _ = ctx.send(
|
|
|
|
|
reply_to,
|
|
|
|
|
NamespaceClientIn::DirectoryReply(DataDirectoryOut::Resolved {
|
|
|
|
|
request_id,
|
|
|
|
|
authority_epoch: self.authority_epoch,
|
|
|
|
|
result,
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
}
|
2026-08-24 15:22:20 +00:00
|
|
|
DataDirectoryIn::Lookup {
|
|
|
|
|
request_id,
|
|
|
|
|
path,
|
|
|
|
|
reply_to,
|
|
|
|
|
} => {
|
|
|
|
|
let result = self.lookup(&path);
|
|
|
|
|
let _ = ctx.send(
|
|
|
|
|
reply_to,
|
|
|
|
|
NamespaceClientIn::DirectoryReply(DataDirectoryOut::LookedUp {
|
|
|
|
|
request_id,
|
|
|
|
|
authority_epoch: self.authority_epoch,
|
|
|
|
|
result,
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
DataDirectoryIn::ReserveBlob {
|
|
|
|
|
request_id,
|
|
|
|
|
path,
|
|
|
|
|
operation_id,
|
|
|
|
|
reply_to,
|
|
|
|
|
} => {
|
|
|
|
|
let result = self.reserve_blob(path, operation_id);
|
|
|
|
|
let _ = ctx.send(
|
|
|
|
|
reply_to,
|
|
|
|
|
NamespaceClientIn::DirectoryReply(DataDirectoryOut::BlobReserved {
|
|
|
|
|
request_id,
|
|
|
|
|
authority_epoch: self.authority_epoch,
|
|
|
|
|
result,
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
DataDirectoryIn::ReleaseBlobReservation {
|
|
|
|
|
request_id,
|
|
|
|
|
path,
|
|
|
|
|
operation_id,
|
|
|
|
|
reply_to,
|
|
|
|
|
} => {
|
|
|
|
|
let result = self.release_blob_reservation(&path, operation_id);
|
|
|
|
|
let _ = ctx.send(
|
|
|
|
|
reply_to,
|
|
|
|
|
NamespaceClientIn::DirectoryReply(DataDirectoryOut::BlobReservationReleased {
|
|
|
|
|
request_id,
|
|
|
|
|
authority_epoch: self.authority_epoch,
|
|
|
|
|
result,
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
}
|
2026-08-22 17:16:56 +00:00
|
|
|
DataDirectoryIn::Unregister {
|
|
|
|
|
request_id,
|
|
|
|
|
path,
|
|
|
|
|
operation_id,
|
|
|
|
|
reply_to,
|
|
|
|
|
} => {
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
if self.streams.contains_key(&path) {
|
|
|
|
|
let _ = ctx.send(
|
|
|
|
|
reply_to,
|
|
|
|
|
NamespaceClientIn::DirectoryReply(DataDirectoryOut::Unregistered {
|
|
|
|
|
request_id,
|
|
|
|
|
authority_epoch: self.authority_epoch,
|
|
|
|
|
result: Err(NamespaceError::WrongEntryType {
|
|
|
|
|
path,
|
|
|
|
|
expected: EntryKind::Blob,
|
|
|
|
|
found: EntryKind::Stream,
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-08-22 17:16:56 +00:00
|
|
|
let replayed = self.store.snapshot().operations.contains_key(&operation_id);
|
|
|
|
|
let retired = (!replayed)
|
|
|
|
|
.then(|| self.sources.get(&path))
|
|
|
|
|
.flatten()
|
|
|
|
|
.and_then(|source| match source {
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
RuntimeSource::Available { actor, .. } => Some(*actor),
|
2026-08-22 17:16:56 +00:00
|
|
|
RuntimeSource::Unavailable(_) => None,
|
|
|
|
|
});
|
|
|
|
|
let result = self.unregister(path, operation_id, retired);
|
|
|
|
|
if result.is_ok()
|
|
|
|
|
&& let Some(retired) = retired
|
|
|
|
|
{
|
2026-08-27 22:09:26 +00:00
|
|
|
self.queue_retirement(ctx, retired);
|
2026-08-22 17:16:56 +00:00
|
|
|
}
|
|
|
|
|
let _ = ctx.send(
|
|
|
|
|
reply_to,
|
|
|
|
|
NamespaceClientIn::DirectoryReply(DataDirectoryOut::Unregistered {
|
|
|
|
|
request_id,
|
|
|
|
|
authority_epoch: self.authority_epoch,
|
|
|
|
|
result,
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
}
|
2026-08-27 22:09:26 +00:00
|
|
|
DataDirectoryIn::Rename {
|
|
|
|
|
request_id,
|
|
|
|
|
source,
|
|
|
|
|
destination,
|
|
|
|
|
replace,
|
|
|
|
|
operation_id,
|
|
|
|
|
reply_to,
|
|
|
|
|
} => {
|
|
|
|
|
let replayed = self.store.snapshot().operations.contains_key(&operation_id);
|
|
|
|
|
let retired = (!replayed && source != destination)
|
|
|
|
|
.then(|| self.sources.get(&destination))
|
|
|
|
|
.flatten()
|
|
|
|
|
.and_then(|source| match source {
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
RuntimeSource::Available { actor, .. } => Some(*actor),
|
2026-08-27 22:09:26 +00:00
|
|
|
RuntimeSource::Unavailable(_) => None,
|
|
|
|
|
});
|
|
|
|
|
let result = self.rename(source, destination, replace, operation_id);
|
|
|
|
|
if result.is_ok()
|
|
|
|
|
&& let Some(retired) = retired
|
|
|
|
|
{
|
|
|
|
|
self.queue_retirement(ctx, retired);
|
|
|
|
|
}
|
|
|
|
|
let _ = ctx.send(
|
|
|
|
|
reply_to,
|
|
|
|
|
NamespaceClientIn::DirectoryReply(DataDirectoryOut::Renamed {
|
|
|
|
|
request_id,
|
|
|
|
|
authority_epoch: self.authority_epoch,
|
|
|
|
|
result,
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
}
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
DataDirectoryIn::OpenStream {
|
|
|
|
|
request_id,
|
|
|
|
|
path,
|
|
|
|
|
role,
|
|
|
|
|
endpoint,
|
|
|
|
|
descriptor,
|
|
|
|
|
replace,
|
2026-08-24 15:22:20 +00:00
|
|
|
ensure,
|
|
|
|
|
expected_revision,
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
operation_id,
|
|
|
|
|
reply_to,
|
|
|
|
|
} => self.open_stream(
|
|
|
|
|
ctx,
|
|
|
|
|
StreamOpenRequest {
|
|
|
|
|
request_id,
|
|
|
|
|
path,
|
|
|
|
|
role,
|
|
|
|
|
endpoint,
|
|
|
|
|
replace,
|
2026-08-24 15:22:20 +00:00
|
|
|
ensure,
|
|
|
|
|
expected_revision,
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
descriptor,
|
|
|
|
|
operation_id,
|
|
|
|
|
reply_to,
|
|
|
|
|
},
|
|
|
|
|
),
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
DataDirectoryIn::CancelStream {
|
|
|
|
|
request_id,
|
|
|
|
|
path,
|
|
|
|
|
operation_id,
|
|
|
|
|
reply_to,
|
|
|
|
|
} => {
|
|
|
|
|
let result = self.cancel_stream(&path, operation_id);
|
|
|
|
|
if let Some(reply_to) = reply_to {
|
|
|
|
|
let _ = ctx.send(
|
|
|
|
|
reply_to,
|
|
|
|
|
NamespaceClientIn::DirectoryReply(DataDirectoryOut::StreamCancelled {
|
|
|
|
|
request_id,
|
|
|
|
|
authority_epoch: self.authority_epoch,
|
|
|
|
|
result,
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
}
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
}
|
|
|
|
|
DataDirectoryIn::CloseStream {
|
|
|
|
|
request_id,
|
|
|
|
|
path,
|
|
|
|
|
incarnation,
|
|
|
|
|
reply_to,
|
|
|
|
|
} => {
|
|
|
|
|
let result = self.close_stream(&path, incarnation);
|
|
|
|
|
let _ = ctx.send(
|
|
|
|
|
reply_to,
|
|
|
|
|
NamespaceClientIn::DirectoryReply(DataDirectoryOut::StreamClosed {
|
|
|
|
|
request_id,
|
|
|
|
|
authority_epoch: self.authority_epoch,
|
|
|
|
|
result,
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
}
|
2026-08-27 22:09:26 +00:00
|
|
|
DataDirectoryIn::SourceRetired { source } => {
|
|
|
|
|
let _ = self.confirm_retirement(source);
|
|
|
|
|
}
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
// The retry tick is the only periodic re-drive of pending
|
|
|
|
|
// retirements: re-fanning on *every* inbound message couples the
|
|
|
|
|
// outbound Retire rate to the cluster's request rate, so a loaded
|
|
|
|
|
// directory (many pending namespace requests) multiplied each
|
|
|
|
|
// unacknowledged retirement into a self-sustaining frame storm
|
|
|
|
|
// that starved namespace replies behind bulk traffic.
|
|
|
|
|
DataDirectoryIn::RetryRetirements => self.retry_retirements(ctx),
|
|
|
|
|
DataDirectoryIn::RetirementRouteChanged { target } => {
|
|
|
|
|
self.retry_retirement(ctx, target);
|
|
|
|
|
}
|
|
|
|
|
DataDirectoryIn::StreamDisplaced {
|
|
|
|
|
endpoint,
|
|
|
|
|
incarnation,
|
|
|
|
|
} => {
|
|
|
|
|
self.confirm_stream_displacement(ctx, endpoint, incarnation);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Drop for DataDirectoryActor {
|
|
|
|
|
fn drop(&mut self) {
|
|
|
|
|
if let Some(timer) = self.retirement_timer.take() {
|
|
|
|
|
timer.cancel();
|
2026-08-22 17:16:56 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub trait NamespaceDiscovery: Send + Sync + 'static {
|
|
|
|
|
fn current_directory(&self) -> Option<ActorAddress>;
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
/// Discoveries carrying a durable authority epoch must validate it exactly
|
|
|
|
|
/// and reject replies while the current authority is undiscovered. A
|
|
|
|
|
/// transport wake alone never authenticates an old authority.
|
|
|
|
|
fn accepts_authority_epoch(&self, _epoch: u64) -> bool {
|
|
|
|
|
true
|
|
|
|
|
}
|
2026-08-22 17:16:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct PendingRequest {
|
|
|
|
|
request: NamespaceRequest,
|
|
|
|
|
reply_to: ActorAddress,
|
2026-08-27 22:09:26 +00:00
|
|
|
enqueued: EngineInstant,
|
2026-08-22 17:16:56 +00:00
|
|
|
}
|
|
|
|
|
|
2026-08-27 22:09:26 +00:00
|
|
|
/// How long a namespace request may stay unanswered while no directory is
|
|
|
|
|
/// discoverable. Authority loss must surface as a bounded typed failure to
|
|
|
|
|
/// callers (e.g. a contextual process blocked on `lookup` after the
|
|
|
|
|
/// orchestrator died), never as a hang.
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
const NAMESPACE_REQUEST_DEADLINE: Duration = Duration::from_secs(80);
|
2026-08-27 22:09:26 +00:00
|
|
|
|
2026-08-22 17:16:56 +00:00
|
|
|
pub struct NamespaceClientActor {
|
|
|
|
|
engine: EngineHandle,
|
|
|
|
|
sender: ExternalSender,
|
|
|
|
|
discovery: Arc<dyn NamespaceDiscovery>,
|
|
|
|
|
retry_period: Duration,
|
2026-08-27 22:09:26 +00:00
|
|
|
request_deadline: Duration,
|
2026-08-22 17:16:56 +00:00
|
|
|
next_request_id: u64,
|
|
|
|
|
pending: HashMap<DirectoryRequestId, PendingRequest>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl NamespaceClientActor {
|
|
|
|
|
pub fn new(
|
|
|
|
|
engine: EngineHandle,
|
|
|
|
|
sender: ExternalSender,
|
|
|
|
|
discovery: Arc<dyn NamespaceDiscovery>,
|
|
|
|
|
retry_period: Duration,
|
2026-08-27 22:09:26 +00:00
|
|
|
) -> Self {
|
|
|
|
|
Self::new_with_deadline(
|
|
|
|
|
engine,
|
|
|
|
|
sender,
|
|
|
|
|
discovery,
|
|
|
|
|
retry_period,
|
|
|
|
|
NAMESPACE_REQUEST_DEADLINE,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn new_with_deadline(
|
|
|
|
|
engine: EngineHandle,
|
|
|
|
|
sender: ExternalSender,
|
|
|
|
|
discovery: Arc<dyn NamespaceDiscovery>,
|
|
|
|
|
retry_period: Duration,
|
|
|
|
|
request_deadline: Duration,
|
2026-08-22 17:16:56 +00:00
|
|
|
) -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
engine,
|
|
|
|
|
sender,
|
|
|
|
|
discovery,
|
|
|
|
|
retry_period,
|
2026-08-27 22:09:26 +00:00
|
|
|
request_deadline,
|
2026-08-22 17:16:56 +00:00
|
|
|
next_request_id: 1,
|
|
|
|
|
pending: HashMap::new(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn dispatch(&self, ctx: &Ctx<'_>, request_id: DirectoryRequestId, request: &NamespaceRequest) {
|
|
|
|
|
let Some(directory) = self.discovery.current_directory() else {
|
|
|
|
|
return;
|
|
|
|
|
};
|
|
|
|
|
let message = match request {
|
|
|
|
|
NamespaceRequest::Register {
|
|
|
|
|
path,
|
|
|
|
|
source,
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
source_node,
|
2026-08-22 17:16:56 +00:00
|
|
|
length,
|
|
|
|
|
recovery,
|
|
|
|
|
operation_id,
|
2026-08-24 15:22:20 +00:00
|
|
|
reservation,
|
2026-08-22 17:16:56 +00:00
|
|
|
} => DataDirectoryIn::Register {
|
|
|
|
|
request_id,
|
|
|
|
|
path: path.clone(),
|
|
|
|
|
source: *source,
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
source_node: *source_node,
|
2026-08-22 17:16:56 +00:00
|
|
|
length: *length,
|
|
|
|
|
recovery: recovery.clone(),
|
|
|
|
|
operation_id: *operation_id,
|
2026-08-24 15:22:20 +00:00
|
|
|
reservation: *reservation,
|
2026-08-22 17:16:56 +00:00
|
|
|
reply_to: ctx.self_addr(),
|
|
|
|
|
},
|
|
|
|
|
NamespaceRequest::Resolve { path } => DataDirectoryIn::Resolve {
|
|
|
|
|
request_id,
|
|
|
|
|
path: path.clone(),
|
|
|
|
|
reply_to: ctx.self_addr(),
|
|
|
|
|
},
|
2026-08-24 15:22:20 +00:00
|
|
|
NamespaceRequest::Lookup { path } => DataDirectoryIn::Lookup {
|
|
|
|
|
request_id,
|
|
|
|
|
path: path.clone(),
|
|
|
|
|
reply_to: ctx.self_addr(),
|
|
|
|
|
},
|
|
|
|
|
NamespaceRequest::ReserveBlob { path, operation_id } => DataDirectoryIn::ReserveBlob {
|
|
|
|
|
request_id,
|
|
|
|
|
path: path.clone(),
|
|
|
|
|
operation_id: *operation_id,
|
|
|
|
|
reply_to: ctx.self_addr(),
|
|
|
|
|
},
|
|
|
|
|
NamespaceRequest::ReleaseBlobReservation { path, operation_id } => {
|
|
|
|
|
DataDirectoryIn::ReleaseBlobReservation {
|
|
|
|
|
request_id,
|
|
|
|
|
path: path.clone(),
|
|
|
|
|
operation_id: *operation_id,
|
|
|
|
|
reply_to: ctx.self_addr(),
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-08-22 17:16:56 +00:00
|
|
|
NamespaceRequest::Unregister { path, operation_id } => DataDirectoryIn::Unregister {
|
|
|
|
|
request_id,
|
|
|
|
|
path: path.clone(),
|
|
|
|
|
operation_id: *operation_id,
|
|
|
|
|
reply_to: ctx.self_addr(),
|
|
|
|
|
},
|
2026-08-27 22:09:26 +00:00
|
|
|
NamespaceRequest::Rename {
|
|
|
|
|
source,
|
|
|
|
|
destination,
|
|
|
|
|
replace,
|
|
|
|
|
operation_id,
|
|
|
|
|
} => DataDirectoryIn::Rename {
|
|
|
|
|
request_id,
|
|
|
|
|
source: source.clone(),
|
|
|
|
|
destination: destination.clone(),
|
|
|
|
|
replace: *replace,
|
|
|
|
|
operation_id: *operation_id,
|
|
|
|
|
reply_to: ctx.self_addr(),
|
|
|
|
|
},
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
NamespaceRequest::OpenStream {
|
|
|
|
|
path,
|
|
|
|
|
role,
|
|
|
|
|
endpoint,
|
|
|
|
|
descriptor,
|
|
|
|
|
replace,
|
2026-08-24 15:22:20 +00:00
|
|
|
ensure,
|
|
|
|
|
expected_revision,
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
operation_id,
|
|
|
|
|
} => DataDirectoryIn::OpenStream {
|
|
|
|
|
request_id,
|
|
|
|
|
path: path.clone(),
|
|
|
|
|
role: *role,
|
|
|
|
|
endpoint: *endpoint,
|
|
|
|
|
descriptor: descriptor.clone(),
|
|
|
|
|
replace: *replace,
|
2026-08-24 15:22:20 +00:00
|
|
|
ensure: *ensure,
|
|
|
|
|
expected_revision: *expected_revision,
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
operation_id: *operation_id,
|
|
|
|
|
reply_to: ctx.self_addr(),
|
|
|
|
|
},
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
NamespaceRequest::CancelStream { path, operation_id } => {
|
|
|
|
|
DataDirectoryIn::CancelStream {
|
|
|
|
|
request_id,
|
|
|
|
|
path: path.clone(),
|
|
|
|
|
operation_id: *operation_id,
|
|
|
|
|
reply_to: Some(ctx.self_addr()),
|
|
|
|
|
}
|
|
|
|
|
}
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
NamespaceRequest::CloseStream { path, incarnation } => DataDirectoryIn::CloseStream {
|
|
|
|
|
request_id,
|
|
|
|
|
path: path.clone(),
|
|
|
|
|
incarnation: *incarnation,
|
|
|
|
|
reply_to: ctx.self_addr(),
|
|
|
|
|
},
|
2026-08-22 17:16:56 +00:00
|
|
|
};
|
|
|
|
|
let _ = ctx.send(directory, message);
|
|
|
|
|
}
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
|
|
|
|
|
/// Enqueue a tracked CancelStream retraction for an abandoned stream
|
|
|
|
|
/// open. The retraction is a pending request the retry tick re-drives
|
|
|
|
|
/// until the directory acknowledges it: a dropped frame would otherwise
|
|
|
|
|
/// strand the parked endpoint in the directory forever, and unlink of
|
|
|
|
|
/// its path would then fail with ENXIO indefinitely.
|
|
|
|
|
fn retract_stream_open(&mut self, ctx: &Ctx<'_>, path: DataPath, operation_id: OperationId) {
|
|
|
|
|
let Some(next) = self
|
|
|
|
|
.next_request_id
|
|
|
|
|
.checked_add(1)
|
|
|
|
|
.filter(|next| *next != 0)
|
|
|
|
|
else {
|
|
|
|
|
return;
|
|
|
|
|
};
|
|
|
|
|
let request_id = DirectoryRequestId(self.next_request_id);
|
|
|
|
|
self.next_request_id = next;
|
|
|
|
|
let request = NamespaceRequest::CancelStream { path, operation_id };
|
|
|
|
|
self.dispatch(ctx, request_id, &request);
|
|
|
|
|
self.pending.insert(
|
|
|
|
|
request_id,
|
|
|
|
|
PendingRequest {
|
|
|
|
|
request,
|
|
|
|
|
reply_to: ctx.self_addr(),
|
|
|
|
|
enqueued: self.engine.now(),
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
2026-08-22 17:16:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl ActorInterface for NamespaceClientActor {
|
|
|
|
|
type Incoming = NamespaceClientIn;
|
|
|
|
|
type Response = ();
|
|
|
|
|
|
|
|
|
|
fn on_start(&mut self, ctx: &Ctx<'_>) {
|
|
|
|
|
self.engine.send_every(
|
|
|
|
|
self.retry_period,
|
|
|
|
|
self.sender.clone(),
|
|
|
|
|
ctx.self_addr(),
|
|
|
|
|
NamespaceClientIn::Retry,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn handle(&mut self, ctx: &Ctx<'_>, message: NamespaceClientIn) {
|
|
|
|
|
match message {
|
|
|
|
|
NamespaceClientIn::Request { request, reply_to } => {
|
|
|
|
|
let request_id = DirectoryRequestId(self.next_request_id);
|
|
|
|
|
let Some(next) = self
|
|
|
|
|
.next_request_id
|
|
|
|
|
.checked_add(1)
|
|
|
|
|
.filter(|next| *next != 0)
|
|
|
|
|
else {
|
|
|
|
|
let _ = ctx.send(
|
|
|
|
|
reply_to,
|
|
|
|
|
DataDirectoryOut::Resolved {
|
|
|
|
|
request_id,
|
|
|
|
|
authority_epoch: 0,
|
|
|
|
|
result: Err(NamespaceError::Protocol(
|
|
|
|
|
"namespace client request IDs exhausted".to_owned(),
|
|
|
|
|
)),
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
};
|
|
|
|
|
self.next_request_id = next;
|
|
|
|
|
self.dispatch(ctx, request_id, &request);
|
2026-08-27 22:09:26 +00:00
|
|
|
self.pending.insert(
|
|
|
|
|
request_id,
|
|
|
|
|
PendingRequest {
|
|
|
|
|
request,
|
|
|
|
|
reply_to,
|
|
|
|
|
enqueued: self.engine.now(),
|
|
|
|
|
},
|
|
|
|
|
);
|
2026-08-22 17:16:56 +00:00
|
|
|
}
|
|
|
|
|
NamespaceClientIn::Cancel { reply_to } => {
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
let cancelled: Vec<(DataPath, OperationId)> = self
|
|
|
|
|
.pending
|
|
|
|
|
.values()
|
|
|
|
|
.filter(|pending| pending.reply_to == reply_to)
|
|
|
|
|
.filter_map(|pending| match &pending.request {
|
|
|
|
|
NamespaceRequest::OpenStream {
|
|
|
|
|
path, operation_id, ..
|
|
|
|
|
} => Some((path.clone(), *operation_id)),
|
|
|
|
|
_ => None,
|
|
|
|
|
})
|
|
|
|
|
.collect();
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
self.pending.retain(|_, pending| {
|
|
|
|
|
if pending.reply_to != reply_to {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
if matches!(
|
|
|
|
|
pending.request,
|
|
|
|
|
NamespaceRequest::CloseStream { .. }
|
|
|
|
|
| NamespaceRequest::CancelStream { .. }
|
|
|
|
|
) {
|
|
|
|
|
// Caller cancellation transfers cleanup ownership to
|
|
|
|
|
// the proxy; it cannot revoke an unacknowledged retract.
|
|
|
|
|
pending.reply_to = ctx.self_addr();
|
|
|
|
|
true
|
|
|
|
|
} else {
|
|
|
|
|
false
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
}
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
});
|
|
|
|
|
// A dropped cancel frame would strand the pending endpoint
|
|
|
|
|
// in the directory forever (nothing else retracts it), so
|
|
|
|
|
// the retraction is tracked as a pending request the retry
|
|
|
|
|
// tick re-drives until the directory acknowledges it.
|
|
|
|
|
for (path, operation_id) in cancelled {
|
|
|
|
|
self.retract_stream_open(ctx, path, operation_id);
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
}
|
2026-08-22 17:16:56 +00:00
|
|
|
}
|
2026-08-24 15:22:20 +00:00
|
|
|
NamespaceClientIn::CancelBlobReservation {
|
|
|
|
|
path,
|
|
|
|
|
operation_id,
|
|
|
|
|
reply_to,
|
|
|
|
|
} => {
|
|
|
|
|
self.pending
|
|
|
|
|
.retain(|_, pending| pending.reply_to != reply_to);
|
|
|
|
|
if let Some(directory) = self.discovery.current_directory() {
|
|
|
|
|
let _ = ctx.send(
|
|
|
|
|
directory,
|
|
|
|
|
DataDirectoryIn::ReleaseBlobReservation {
|
|
|
|
|
request_id: DirectoryRequestId(0),
|
|
|
|
|
path,
|
|
|
|
|
operation_id,
|
|
|
|
|
reply_to: ctx.self_addr(),
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-08-22 17:16:56 +00:00
|
|
|
NamespaceClientIn::DirectoryReply(reply) => {
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
if !self
|
|
|
|
|
.discovery
|
|
|
|
|
.accepts_authority_epoch(reply.authority_epoch())
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-08-22 17:16:56 +00:00
|
|
|
if let Some(pending) = self.pending.remove(&reply.request_id()) {
|
|
|
|
|
let _ = ctx.send(pending.reply_to, reply);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
NamespaceClientIn::TransferFailed {
|
|
|
|
|
destination,
|
|
|
|
|
transfer_id,
|
|
|
|
|
reason,
|
|
|
|
|
} => {
|
|
|
|
|
let _ = ctx.send(
|
|
|
|
|
destination,
|
|
|
|
|
BlobTransferEvent::Failed {
|
|
|
|
|
transfer_id,
|
|
|
|
|
reason,
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
NamespaceClientIn::Retry => {
|
2026-08-27 22:09:26 +00:00
|
|
|
// A request no directory has answered within the bound fails
|
|
|
|
|
// with a typed error instead of hanging the caller forever
|
|
|
|
|
// (e.g. authority loss — the registry may keep serving the
|
|
|
|
|
// dead directory's address, so age is the only sound bound).
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
// Stream retractions are exempt: a CloseStream or
|
|
|
|
|
// CancelStream that expires while the directory is
|
|
|
|
|
// unreachable would strand the endpoint in the directory
|
|
|
|
|
// forever — unlink of that path then fails with ENXIO
|
|
|
|
|
// indefinitely — while every later request flows again.
|
|
|
|
|
// Retractions have no caller left to disappoint; they retry
|
|
|
|
|
// until the directory acknowledges them.
|
2026-08-27 22:09:26 +00:00
|
|
|
let now = self.engine.now();
|
|
|
|
|
let expired: Vec<DirectoryRequestId> = self
|
|
|
|
|
.pending
|
|
|
|
|
.iter()
|
|
|
|
|
.filter(|(_, pending)| {
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
!matches!(
|
|
|
|
|
pending.request,
|
|
|
|
|
NamespaceRequest::CloseStream { .. }
|
|
|
|
|
| NamespaceRequest::CancelStream { .. }
|
|
|
|
|
) && now
|
|
|
|
|
.to_instant()
|
2026-08-27 22:09:26 +00:00
|
|
|
.duration_since(pending.enqueued.to_instant())
|
|
|
|
|
> self.request_deadline
|
|
|
|
|
})
|
|
|
|
|
.map(|(request_id, _)| *request_id)
|
|
|
|
|
.collect();
|
|
|
|
|
for request_id in expired {
|
|
|
|
|
if let Some(pending) = self.pending.remove(&request_id) {
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
// An expired stream open may already be registered
|
|
|
|
|
// in the directory: first-role opens park without a
|
|
|
|
|
// reply until their peer arrives, so the deadline
|
|
|
|
|
// fires while the endpoint is committed. Its caller
|
|
|
|
|
// is gone with the failure reply — nothing else
|
|
|
|
|
// retracts the open — so the expiry itself must
|
|
|
|
|
// enqueue the same deadline-exempt retraction the
|
|
|
|
|
// cancel path uses. Without it the parked endpoint
|
|
|
|
|
// survives forever and unlink of the path fails
|
|
|
|
|
// with ENXIO indefinitely.
|
|
|
|
|
if let NamespaceRequest::OpenStream {
|
|
|
|
|
path, operation_id, ..
|
|
|
|
|
} = &pending.request
|
|
|
|
|
{
|
|
|
|
|
self.retract_stream_open(ctx, path.clone(), *operation_id);
|
|
|
|
|
}
|
2026-08-27 22:09:26 +00:00
|
|
|
let _ = ctx.send(
|
|
|
|
|
pending.reply_to,
|
|
|
|
|
expired_reply(request_id, &pending.request),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-08-22 17:16:56 +00:00
|
|
|
for (request_id, pending) in &self.pending {
|
|
|
|
|
self.dispatch(ctx, *request_id, &pending.request);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-27 22:09:26 +00:00
|
|
|
/// Build the typed failure a caller receives when its namespace request
|
|
|
|
|
fn expired_reply(request_id: DirectoryRequestId, request: &NamespaceRequest) -> DataDirectoryOut {
|
|
|
|
|
fn failure<T>() -> Result<T, NamespaceError> {
|
|
|
|
|
Err(NamespaceError::DirectoryUnavailable(
|
|
|
|
|
"no namespace authority was discoverable within the request deadline".to_owned(),
|
|
|
|
|
))
|
|
|
|
|
}
|
|
|
|
|
match request {
|
|
|
|
|
NamespaceRequest::Register { .. } => DataDirectoryOut::Registered {
|
|
|
|
|
request_id,
|
|
|
|
|
authority_epoch: 0,
|
|
|
|
|
result: failure(),
|
|
|
|
|
},
|
|
|
|
|
NamespaceRequest::Resolve { .. } => DataDirectoryOut::Resolved {
|
|
|
|
|
request_id,
|
|
|
|
|
authority_epoch: 0,
|
|
|
|
|
result: failure(),
|
|
|
|
|
},
|
|
|
|
|
NamespaceRequest::Lookup { .. } => DataDirectoryOut::LookedUp {
|
|
|
|
|
request_id,
|
|
|
|
|
authority_epoch: 0,
|
|
|
|
|
result: failure(),
|
|
|
|
|
},
|
|
|
|
|
NamespaceRequest::ReserveBlob { .. } => DataDirectoryOut::BlobReserved {
|
|
|
|
|
request_id,
|
|
|
|
|
authority_epoch: 0,
|
|
|
|
|
result: failure(),
|
|
|
|
|
},
|
|
|
|
|
NamespaceRequest::ReleaseBlobReservation { .. } => {
|
|
|
|
|
DataDirectoryOut::BlobReservationReleased {
|
|
|
|
|
request_id,
|
|
|
|
|
authority_epoch: 0,
|
|
|
|
|
result: failure(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
NamespaceRequest::Unregister { .. } => DataDirectoryOut::Unregistered {
|
|
|
|
|
request_id,
|
|
|
|
|
authority_epoch: 0,
|
|
|
|
|
result: failure(),
|
|
|
|
|
},
|
|
|
|
|
NamespaceRequest::Rename { .. } => DataDirectoryOut::Renamed {
|
|
|
|
|
request_id,
|
|
|
|
|
authority_epoch: 0,
|
|
|
|
|
result: failure(),
|
|
|
|
|
},
|
|
|
|
|
NamespaceRequest::OpenStream { .. } => DataDirectoryOut::StreamOpened {
|
|
|
|
|
request_id,
|
|
|
|
|
authority_epoch: 0,
|
|
|
|
|
result: failure(),
|
|
|
|
|
},
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
NamespaceRequest::CancelStream { .. } => DataDirectoryOut::StreamCancelled {
|
|
|
|
|
request_id,
|
|
|
|
|
authority_epoch: 0,
|
|
|
|
|
result: failure(),
|
|
|
|
|
},
|
2026-08-27 22:09:26 +00:00
|
|
|
NamespaceRequest::CloseStream { .. } => DataDirectoryOut::StreamClosed {
|
|
|
|
|
request_id,
|
|
|
|
|
authority_epoch: 0,
|
|
|
|
|
result: failure(),
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-22 17:16:56 +00:00
|
|
|
struct NamespaceRequestCancellation {
|
|
|
|
|
runtime: Runtime,
|
|
|
|
|
proxy: ActorAddress,
|
|
|
|
|
reply_to: ActorAddress,
|
|
|
|
|
armed: bool,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Drop for NamespaceRequestCancellation {
|
|
|
|
|
fn drop(&mut self) {
|
|
|
|
|
if self.armed {
|
|
|
|
|
let _ = self.runtime.send_to(
|
|
|
|
|
self.proxy,
|
|
|
|
|
NamespaceClientIn::Cancel {
|
|
|
|
|
reply_to: self.reply_to,
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
|
pub struct NamespaceClient {
|
|
|
|
|
runtime: Runtime,
|
|
|
|
|
proxy: ActorAddress,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl NamespaceClient {
|
|
|
|
|
pub fn new(runtime: Runtime, proxy: ActorAddress) -> Self {
|
|
|
|
|
Self { runtime, proxy }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn proxy(&self) -> ActorAddress {
|
|
|
|
|
self.proxy
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async fn request(&self, request: NamespaceRequest) -> Result<DataDirectoryOut, NamespaceError> {
|
|
|
|
|
let inbox = self
|
|
|
|
|
.runtime
|
|
|
|
|
.new_inbox::<DataDirectoryOut>()
|
|
|
|
|
.map_err(|error| NamespaceError::DirectoryUnavailable(error.to_string()))?;
|
|
|
|
|
let reply_to = *inbox.addr();
|
|
|
|
|
self.runtime
|
|
|
|
|
.send_to(self.proxy, NamespaceClientIn::Request { request, reply_to })
|
|
|
|
|
.map_err(|error| NamespaceError::DirectoryUnavailable(error.to_string()))?;
|
|
|
|
|
let mut cancellation = NamespaceRequestCancellation {
|
|
|
|
|
runtime: self.runtime.clone(),
|
|
|
|
|
proxy: self.proxy,
|
|
|
|
|
reply_to,
|
|
|
|
|
armed: true,
|
|
|
|
|
};
|
|
|
|
|
let reply = inbox.recv().await;
|
|
|
|
|
cancellation.armed = false;
|
|
|
|
|
Ok(reply)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub async fn register(
|
|
|
|
|
&self,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
source: ActorAddress,
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
source_node: [u8; 32],
|
2026-08-22 17:16:56 +00:00
|
|
|
length: u64,
|
|
|
|
|
recovery: SourceRecovery,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
) -> Result<MutationReceipt, NamespaceError> {
|
|
|
|
|
match self
|
|
|
|
|
.request(NamespaceRequest::Register {
|
|
|
|
|
path,
|
|
|
|
|
source,
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
source_node,
|
2026-08-22 17:16:56 +00:00
|
|
|
length,
|
|
|
|
|
recovery,
|
|
|
|
|
operation_id,
|
2026-08-24 15:22:20 +00:00
|
|
|
reservation: None,
|
2026-08-22 17:16:56 +00:00
|
|
|
})
|
|
|
|
|
.await?
|
|
|
|
|
{
|
|
|
|
|
DataDirectoryOut::Registered { result, .. } => result,
|
|
|
|
|
other => Err(NamespaceError::Protocol(format!(
|
|
|
|
|
"expected register reply, received {other:?}"
|
|
|
|
|
))),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub async fn resolve(&self, path: DataPath) -> Result<BlobBinding, NamespaceError> {
|
|
|
|
|
match self.request(NamespaceRequest::Resolve { path }).await? {
|
|
|
|
|
DataDirectoryOut::Resolved { result, .. } => result,
|
|
|
|
|
other => Err(NamespaceError::Protocol(format!(
|
|
|
|
|
"expected resolve reply, received {other:?}"
|
|
|
|
|
))),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-24 15:22:20 +00:00
|
|
|
pub async fn lookup(&self, path: DataPath) -> Result<NamespaceNode, NamespaceError> {
|
|
|
|
|
match self.request(NamespaceRequest::Lookup { path }).await? {
|
|
|
|
|
DataDirectoryOut::LookedUp { result, .. } => result,
|
|
|
|
|
other => Err(NamespaceError::Protocol(format!(
|
|
|
|
|
"expected lookup reply, received {other:?}"
|
|
|
|
|
))),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-22 17:16:56 +00:00
|
|
|
pub async fn unregister(
|
|
|
|
|
&self,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
) -> Result<MutationReceipt, NamespaceError> {
|
|
|
|
|
match self
|
|
|
|
|
.request(NamespaceRequest::Unregister { path, operation_id })
|
|
|
|
|
.await?
|
|
|
|
|
{
|
|
|
|
|
DataDirectoryOut::Unregistered { result, .. } => result,
|
|
|
|
|
other => Err(NamespaceError::Protocol(format!(
|
|
|
|
|
"expected unregister reply, received {other:?}"
|
|
|
|
|
))),
|
|
|
|
|
}
|
|
|
|
|
}
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
|
2026-08-27 22:09:26 +00:00
|
|
|
pub async fn rename(
|
|
|
|
|
&self,
|
|
|
|
|
source: DataPath,
|
|
|
|
|
destination: DataPath,
|
|
|
|
|
replace: bool,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
) -> Result<MutationReceipt, NamespaceError> {
|
|
|
|
|
match self
|
|
|
|
|
.request(NamespaceRequest::Rename {
|
|
|
|
|
source,
|
|
|
|
|
destination,
|
|
|
|
|
replace,
|
|
|
|
|
operation_id,
|
|
|
|
|
})
|
|
|
|
|
.await?
|
|
|
|
|
{
|
|
|
|
|
DataDirectoryOut::Renamed { result, .. } => result,
|
|
|
|
|
other => Err(NamespaceError::Protocol(format!(
|
|
|
|
|
"expected rename reply, received {other:?}"
|
|
|
|
|
))),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
async fn open_stream_inner(
|
|
|
|
|
&self,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
role: StreamRole,
|
|
|
|
|
endpoint: ActorAddress,
|
|
|
|
|
replace: bool,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
) -> Result<StreamMatch, NamespaceError> {
|
|
|
|
|
match self
|
|
|
|
|
.request(NamespaceRequest::OpenStream {
|
|
|
|
|
path,
|
|
|
|
|
role,
|
|
|
|
|
endpoint,
|
|
|
|
|
replace,
|
2026-08-24 15:22:20 +00:00
|
|
|
ensure: true,
|
|
|
|
|
expected_revision: None,
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
descriptor: Vec::new(),
|
|
|
|
|
operation_id,
|
|
|
|
|
})
|
|
|
|
|
.await?
|
|
|
|
|
{
|
|
|
|
|
DataDirectoryOut::StreamOpened { result, .. } => result,
|
|
|
|
|
other => Err(NamespaceError::Protocol(format!(
|
|
|
|
|
"expected stream-open reply, received {other:?}"
|
|
|
|
|
))),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub async fn open_stream(
|
|
|
|
|
&self,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
role: StreamRole,
|
|
|
|
|
endpoint: ActorAddress,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
) -> Result<StreamMatch, NamespaceError> {
|
|
|
|
|
self.open_stream_inner(path, role, endpoint, false, operation_id)
|
|
|
|
|
.await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub async fn replace_with_stream(
|
|
|
|
|
&self,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
role: StreamRole,
|
|
|
|
|
endpoint: ActorAddress,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
) -> Result<StreamMatch, NamespaceError> {
|
|
|
|
|
self.open_stream_inner(path, role, endpoint, true, operation_id)
|
|
|
|
|
.await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub async fn close_stream(
|
|
|
|
|
&self,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
incarnation: StreamIncarnation,
|
|
|
|
|
) -> Result<(), NamespaceError> {
|
|
|
|
|
match self
|
|
|
|
|
.request(NamespaceRequest::CloseStream { path, incarnation })
|
|
|
|
|
.await?
|
|
|
|
|
{
|
|
|
|
|
DataDirectoryOut::StreamClosed { result, .. } => result,
|
|
|
|
|
other => Err(NamespaceError::Protocol(format!(
|
|
|
|
|
"expected stream-close reply, received {other:?}"
|
|
|
|
|
))),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct DirectoryStreamCancellation {
|
|
|
|
|
runtime: Runtime,
|
|
|
|
|
directory: ActorAddress,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
armed: bool,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Drop for DirectoryStreamCancellation {
|
|
|
|
|
fn drop(&mut self) {
|
|
|
|
|
if self.armed {
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
// Fire-and-forget: this path is unused in production (stream
|
|
|
|
|
// opens route through the retrying namespace proxy); the
|
|
|
|
|
// durable cancel tombstone still makes a lost frame safe
|
|
|
|
|
// against a later replay of the same open.
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
let _ = self.runtime.send_to(
|
|
|
|
|
self.directory,
|
|
|
|
|
DataDirectoryIn::CancelStream {
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
request_id: DirectoryRequestId(0),
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
path: self.path.clone(),
|
|
|
|
|
operation_id: self.operation_id,
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
reply_to: None,
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-08-22 17:16:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
|
pub struct DirectoryClient {
|
|
|
|
|
runtime: Runtime,
|
|
|
|
|
directory: ActorAddress,
|
|
|
|
|
next_request_id: Arc<AtomicU64>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl DirectoryClient {
|
|
|
|
|
pub fn new(runtime: Runtime, directory: ActorAddress) -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
runtime,
|
|
|
|
|
directory,
|
|
|
|
|
next_request_id: Arc::new(AtomicU64::new(1)),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn directory(&self) -> ActorAddress {
|
|
|
|
|
self.directory
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn request_id(&self) -> DirectoryRequestId {
|
|
|
|
|
DirectoryRequestId(self.next_request_id.fetch_add(1, Ordering::Relaxed))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async fn receive(
|
|
|
|
|
&self,
|
|
|
|
|
inbox: &swactor::runtime::Inbox<NamespaceClientIn>,
|
|
|
|
|
) -> Result<DataDirectoryOut, NamespaceError> {
|
|
|
|
|
match inbox.recv().await {
|
|
|
|
|
NamespaceClientIn::DirectoryReply(reply) => Ok(reply),
|
|
|
|
|
other => Err(NamespaceError::Protocol(format!(
|
|
|
|
|
"expected directory reply, received {other:?}"
|
|
|
|
|
))),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub async fn register(
|
|
|
|
|
&self,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
source: ActorAddress,
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
source_node: [u8; 32],
|
2026-08-22 17:16:56 +00:00
|
|
|
length: u64,
|
|
|
|
|
recovery: SourceRecovery,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
) -> Result<MutationReceipt, NamespaceError> {
|
|
|
|
|
let inbox = self
|
|
|
|
|
.runtime
|
|
|
|
|
.new_inbox::<NamespaceClientIn>()
|
|
|
|
|
.map_err(|error| NamespaceError::DirectoryUnavailable(error.to_string()))?;
|
|
|
|
|
self.runtime
|
|
|
|
|
.send_to(
|
|
|
|
|
self.directory,
|
|
|
|
|
DataDirectoryIn::Register {
|
|
|
|
|
request_id: self.request_id(),
|
|
|
|
|
path,
|
|
|
|
|
source,
|
runtime: checkpoint distributed execution and retained-node deployment
Integrate namespace and source-route lifecycle changes, contextual process cleanup, Python binding updates, and Myelin worker/orchestrator recovery. Keep the shared control contracts, deployment identity fencing, SSH bootstrap adapters, paid admission accounting, and VastAI cleanup implementation together with their consumers.
Migrate Iroh dependencies and telemetry transport/collection with dashboard and demo callsites, workspace build configuration, and actor-control-flow policy updates. This is an intermediate development checkpoint, not paid-provider qualification.
Review verification: contextual_process_guarantees (4 tests), telemetry_transport (4 tests), and shared control contracts (5 tests) passed. Historical five-node redeployment and campaign execution passed individually; complete ordered qualification remains pending.
2026-09-14 09:20:56 +00:00
|
|
|
source_node,
|
2026-08-22 17:16:56 +00:00
|
|
|
length,
|
|
|
|
|
recovery,
|
|
|
|
|
operation_id,
|
2026-08-24 15:22:20 +00:00
|
|
|
reservation: None,
|
2026-08-22 17:16:56 +00:00
|
|
|
reply_to: *inbox.addr(),
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
.map_err(|error| NamespaceError::DirectoryUnavailable(error.to_string()))?;
|
|
|
|
|
match self.receive(&inbox).await? {
|
|
|
|
|
DataDirectoryOut::Registered { result, .. } => result,
|
|
|
|
|
other => Err(NamespaceError::Protocol(format!(
|
|
|
|
|
"expected register reply, received {other:?}"
|
|
|
|
|
))),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub async fn resolve(&self, path: DataPath) -> Result<BlobBinding, NamespaceError> {
|
|
|
|
|
let inbox = self
|
|
|
|
|
.runtime
|
|
|
|
|
.new_inbox::<NamespaceClientIn>()
|
|
|
|
|
.map_err(|error| NamespaceError::DirectoryUnavailable(error.to_string()))?;
|
|
|
|
|
self.runtime
|
|
|
|
|
.send_to(
|
|
|
|
|
self.directory,
|
|
|
|
|
DataDirectoryIn::Resolve {
|
|
|
|
|
request_id: self.request_id(),
|
|
|
|
|
path,
|
|
|
|
|
reply_to: *inbox.addr(),
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
.map_err(|error| NamespaceError::DirectoryUnavailable(error.to_string()))?;
|
|
|
|
|
match self.receive(&inbox).await? {
|
|
|
|
|
DataDirectoryOut::Resolved { result, .. } => result,
|
|
|
|
|
other => Err(NamespaceError::Protocol(format!(
|
|
|
|
|
"expected resolve reply, received {other:?}"
|
|
|
|
|
))),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-24 15:22:20 +00:00
|
|
|
pub async fn lookup(&self, path: DataPath) -> Result<NamespaceNode, NamespaceError> {
|
|
|
|
|
let inbox = self
|
|
|
|
|
.runtime
|
|
|
|
|
.new_inbox::<NamespaceClientIn>()
|
|
|
|
|
.map_err(|error| NamespaceError::DirectoryUnavailable(error.to_string()))?;
|
|
|
|
|
self.runtime
|
|
|
|
|
.send_to(
|
|
|
|
|
self.directory,
|
|
|
|
|
DataDirectoryIn::Lookup {
|
|
|
|
|
request_id: self.request_id(),
|
|
|
|
|
path,
|
|
|
|
|
reply_to: *inbox.addr(),
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
.map_err(|error| NamespaceError::DirectoryUnavailable(error.to_string()))?;
|
|
|
|
|
match self.receive(&inbox).await? {
|
|
|
|
|
DataDirectoryOut::LookedUp { result, .. } => result,
|
|
|
|
|
other => Err(NamespaceError::Protocol(format!(
|
|
|
|
|
"expected lookup reply, received {other:?}"
|
|
|
|
|
))),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-22 17:16:56 +00:00
|
|
|
pub async fn unregister(
|
|
|
|
|
&self,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
) -> Result<MutationReceipt, NamespaceError> {
|
|
|
|
|
let inbox = self
|
|
|
|
|
.runtime
|
|
|
|
|
.new_inbox::<NamespaceClientIn>()
|
|
|
|
|
.map_err(|error| NamespaceError::DirectoryUnavailable(error.to_string()))?;
|
|
|
|
|
self.runtime
|
|
|
|
|
.send_to(
|
|
|
|
|
self.directory,
|
|
|
|
|
DataDirectoryIn::Unregister {
|
|
|
|
|
request_id: self.request_id(),
|
|
|
|
|
path,
|
|
|
|
|
operation_id,
|
|
|
|
|
reply_to: *inbox.addr(),
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
.map_err(|error| NamespaceError::DirectoryUnavailable(error.to_string()))?;
|
|
|
|
|
match self.receive(&inbox).await? {
|
|
|
|
|
DataDirectoryOut::Unregistered { result, .. } => result,
|
|
|
|
|
other => Err(NamespaceError::Protocol(format!(
|
|
|
|
|
"expected unregister reply, received {other:?}"
|
|
|
|
|
))),
|
|
|
|
|
}
|
|
|
|
|
}
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
|
2026-08-27 22:09:26 +00:00
|
|
|
pub async fn rename(
|
|
|
|
|
&self,
|
|
|
|
|
source: DataPath,
|
|
|
|
|
destination: DataPath,
|
|
|
|
|
replace: bool,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
) -> Result<MutationReceipt, NamespaceError> {
|
|
|
|
|
let inbox = self
|
|
|
|
|
.runtime
|
|
|
|
|
.new_inbox::<NamespaceClientIn>()
|
|
|
|
|
.map_err(|error| NamespaceError::DirectoryUnavailable(error.to_string()))?;
|
|
|
|
|
self.runtime
|
|
|
|
|
.send_to(
|
|
|
|
|
self.directory,
|
|
|
|
|
DataDirectoryIn::Rename {
|
|
|
|
|
request_id: self.request_id(),
|
|
|
|
|
source,
|
|
|
|
|
destination,
|
|
|
|
|
replace,
|
|
|
|
|
operation_id,
|
|
|
|
|
reply_to: *inbox.addr(),
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
.map_err(|error| NamespaceError::DirectoryUnavailable(error.to_string()))?;
|
|
|
|
|
match self.receive(&inbox).await? {
|
|
|
|
|
DataDirectoryOut::Renamed { result, .. } => result,
|
|
|
|
|
other => Err(NamespaceError::Protocol(format!(
|
|
|
|
|
"expected rename reply, received {other:?}"
|
|
|
|
|
))),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub async fn reserve_blob(
|
|
|
|
|
&self,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
) -> Result<(), NamespaceError> {
|
|
|
|
|
let inbox = self
|
|
|
|
|
.runtime
|
|
|
|
|
.new_inbox::<NamespaceClientIn>()
|
|
|
|
|
.map_err(|error| NamespaceError::DirectoryUnavailable(error.to_string()))?;
|
|
|
|
|
self.runtime
|
|
|
|
|
.send_to(
|
|
|
|
|
self.directory,
|
|
|
|
|
DataDirectoryIn::ReserveBlob {
|
|
|
|
|
request_id: self.request_id(),
|
|
|
|
|
path,
|
|
|
|
|
operation_id,
|
|
|
|
|
reply_to: *inbox.addr(),
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
.map_err(|error| NamespaceError::DirectoryUnavailable(error.to_string()))?;
|
|
|
|
|
match self.receive(&inbox).await? {
|
|
|
|
|
DataDirectoryOut::BlobReserved { result, .. } => result,
|
|
|
|
|
other => Err(NamespaceError::Protocol(format!(
|
|
|
|
|
"expected reserve reply, received {other:?}"
|
|
|
|
|
))),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub async fn release_blob_reservation(
|
|
|
|
|
&self,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
) -> Result<(), NamespaceError> {
|
|
|
|
|
let inbox = self
|
|
|
|
|
.runtime
|
|
|
|
|
.new_inbox::<NamespaceClientIn>()
|
|
|
|
|
.map_err(|error| NamespaceError::DirectoryUnavailable(error.to_string()))?;
|
|
|
|
|
self.runtime
|
|
|
|
|
.send_to(
|
|
|
|
|
self.directory,
|
|
|
|
|
DataDirectoryIn::ReleaseBlobReservation {
|
|
|
|
|
request_id: self.request_id(),
|
|
|
|
|
path,
|
|
|
|
|
operation_id,
|
|
|
|
|
reply_to: *inbox.addr(),
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
.map_err(|error| NamespaceError::DirectoryUnavailable(error.to_string()))?;
|
|
|
|
|
match self.receive(&inbox).await? {
|
|
|
|
|
DataDirectoryOut::BlobReservationReleased { result, .. } => result,
|
|
|
|
|
other => Err(NamespaceError::Protocol(format!(
|
|
|
|
|
"expected release reply, received {other:?}"
|
|
|
|
|
))),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
async fn open_stream_inner(
|
|
|
|
|
&self,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
role: StreamRole,
|
|
|
|
|
endpoint: ActorAddress,
|
|
|
|
|
replace: bool,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
) -> Result<StreamMatch, NamespaceError> {
|
|
|
|
|
let inbox = self
|
|
|
|
|
.runtime
|
|
|
|
|
.new_inbox::<NamespaceClientIn>()
|
|
|
|
|
.map_err(|error| NamespaceError::DirectoryUnavailable(error.to_string()))?;
|
|
|
|
|
let mut cancellation = DirectoryStreamCancellation {
|
|
|
|
|
runtime: self.runtime.clone(),
|
|
|
|
|
directory: self.directory,
|
|
|
|
|
path: path.clone(),
|
|
|
|
|
operation_id,
|
|
|
|
|
armed: true,
|
|
|
|
|
};
|
|
|
|
|
self.runtime
|
|
|
|
|
.send_to(
|
|
|
|
|
self.directory,
|
|
|
|
|
DataDirectoryIn::OpenStream {
|
|
|
|
|
request_id: self.request_id(),
|
|
|
|
|
path,
|
|
|
|
|
role,
|
|
|
|
|
endpoint,
|
|
|
|
|
replace,
|
2026-08-24 15:22:20 +00:00
|
|
|
ensure: true,
|
|
|
|
|
expected_revision: None,
|
feat(data-plane): add routed SPSC stream transport
Implement namespace-owned stream rendezvous with incarnation isolation, cancellation, recovery, bounded local byte rings, and host/child actor protocols.
Add a replaceable stream transport boundary plus an Iroh ALPN adapter with framed records, backpressure, reconnect handling, and terminal propagation.
Wire stream sources and sinks through Myelin job deployment and Python bindings, with guarantee coverage across blob, namespace, job, byte-ring, and transport paths.
Sanitize nested Cargo build context in xtask so lint, Nextest, doctest, and maturin invocations retain stable fingerprints.
2026-08-23 08:47:31 +00:00
|
|
|
operation_id,
|
|
|
|
|
descriptor: Vec::new(),
|
|
|
|
|
reply_to: *inbox.addr(),
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
.map_err(|error| NamespaceError::DirectoryUnavailable(error.to_string()))?;
|
|
|
|
|
let result = match self.receive(&inbox).await? {
|
|
|
|
|
DataDirectoryOut::StreamOpened { result, .. } => result,
|
|
|
|
|
other => Err(NamespaceError::Protocol(format!(
|
|
|
|
|
"expected stream-open reply, received {other:?}"
|
|
|
|
|
))),
|
|
|
|
|
};
|
|
|
|
|
cancellation.armed = false;
|
|
|
|
|
result
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub async fn open_stream(
|
|
|
|
|
&self,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
role: StreamRole,
|
|
|
|
|
endpoint: ActorAddress,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
) -> Result<StreamMatch, NamespaceError> {
|
|
|
|
|
self.open_stream_inner(path, role, endpoint, false, operation_id)
|
|
|
|
|
.await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub async fn replace_with_stream(
|
|
|
|
|
&self,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
role: StreamRole,
|
|
|
|
|
endpoint: ActorAddress,
|
|
|
|
|
operation_id: OperationId,
|
|
|
|
|
) -> Result<StreamMatch, NamespaceError> {
|
|
|
|
|
self.open_stream_inner(path, role, endpoint, true, operation_id)
|
|
|
|
|
.await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub async fn close_stream(
|
|
|
|
|
&self,
|
|
|
|
|
path: DataPath,
|
|
|
|
|
incarnation: StreamIncarnation,
|
|
|
|
|
) -> Result<(), NamespaceError> {
|
|
|
|
|
let inbox = self
|
|
|
|
|
.runtime
|
|
|
|
|
.new_inbox::<NamespaceClientIn>()
|
|
|
|
|
.map_err(|error| NamespaceError::DirectoryUnavailable(error.to_string()))?;
|
|
|
|
|
self.runtime
|
|
|
|
|
.send_to(
|
|
|
|
|
self.directory,
|
|
|
|
|
DataDirectoryIn::CloseStream {
|
|
|
|
|
request_id: self.request_id(),
|
|
|
|
|
path,
|
|
|
|
|
incarnation,
|
|
|
|
|
reply_to: *inbox.addr(),
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
.map_err(|error| NamespaceError::DirectoryUnavailable(error.to_string()))?;
|
|
|
|
|
match self.receive(&inbox).await? {
|
|
|
|
|
DataDirectoryOut::StreamClosed { result, .. } => result,
|
|
|
|
|
other => Err(NamespaceError::Protocol(format!(
|
|
|
|
|
"expected stream-close reply, received {other:?}"
|
|
|
|
|
))),
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-08-22 17:16:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn register_namespace_codecs(registry: &mut CodecRegistry) {
|
2026-08-24 09:51:42 +00:00
|
|
|
registry
|
|
|
|
|
.register::<DataDirectoryIn, _>(JsonCodec::default())
|
|
|
|
|
.expect("unique codec registration");
|
|
|
|
|
registry
|
|
|
|
|
.register::<NamespaceClientIn, _>(JsonCodec::default())
|
|
|
|
|
.expect("unique codec registration");
|
2026-08-22 17:16:56 +00:00
|
|
|
}
|