refactor: fold driver pumps into iroh-driver and codecs into transport
Consolidate the duplicated JSON codec into `transport` and relocate the iroh edge-transport pieces into `iroh-driver`, dissolving the `mvp-system` transport shim. - `transport`: add a canonical `json_codec::JsonCodec<M>` (re-exported from the crate root) as the single JSON codec for serde message types - `distribution`/`datastream`: drop the per-crate `JsonCodec` copies and the `impl_json_codec!` macro; register SWIM/gossip and publisher messages against the shared `swactor_transport::JsonCodec` - `iroh-driver`: move `driver_pumps` and `endpoint_advertisement` out of `mvp-system/src/transport/`, re-exporting `EndpointAddrMask`/`advertised_endpoint`/`MVP_IROH_ENDPOINT_ADDR_MASK_ENV`, and relocate the endpoint guarantee test to `iroh-driver/tests/endpoint_advertisement.rs` - `mvp-system`: delete the `transport/` module and keep codec aggregation in a new `codecs.rs` (`register_mvp_actor_codecs`) - `mvp-system/node`: shrink `worker_node_runtime.rs` (~260 lines) by adopting the relocated modules and collapsing verbose `emit_stdio_node_event` calls into local `boot()`/`worker_evt()` closures Signed-off-by: Zachery Aaron Shores-Chmielewski <zacheryasc@gmail.com>
This commit is contained in:
parent
fdfb639f7d
commit
c257dde02f
19 changed files with 156 additions and 313 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -5,6 +5,7 @@ corpus
|
||||||
.loop/
|
.loop/
|
||||||
.model-cache/
|
.model-cache/
|
||||||
.deployment-notes/
|
.deployment-notes/
|
||||||
|
.omp/
|
||||||
|
|
||||||
# environment variables for deployment configurations
|
# environment variables for deployment configurations
|
||||||
.config/
|
.config/
|
||||||
|
|
@ -5,17 +5,13 @@
|
||||||
//! injected by the runtime crate so the datastream core does not depend on the
|
//! injected by the runtime crate so the datastream core does not depend on the
|
||||||
//! concrete QUIC writer implementation.
|
//! concrete QUIC writer implementation.
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use iroh::EndpointAddr;
|
use iroh::EndpointAddr;
|
||||||
use serde::Serialize;
|
|
||||||
use serde::de::DeserializeOwned;
|
|
||||||
use serde::{Deserialize, Serialize as DeriveSerialize};
|
use serde::{Deserialize, Serialize as DeriveSerialize};
|
||||||
use swactor::Error;
|
|
||||||
use swactor::actor::ActorInterface;
|
use swactor::actor::ActorInterface;
|
||||||
use swactor::runtime::Ctx;
|
use swactor::runtime::Ctx;
|
||||||
use swactor_transport::{Codec, CodecRegistry, NetworkMessage};
|
use swactor_transport::{CodecRegistry, JsonCodec, NetworkMessage};
|
||||||
|
|
||||||
use crate::{DatastreamEndpoint, DatastreamSubscription, SubscriptionRequest};
|
use crate::{DatastreamEndpoint, DatastreamSubscription, SubscriptionRequest};
|
||||||
|
|
||||||
|
|
@ -80,22 +76,7 @@ impl ActorInterface for DatastreamPublisherActor {
|
||||||
|
|
||||||
/// Register JSON encoding for remote datastream publisher messages.
|
/// Register JSON encoding for remote datastream publisher messages.
|
||||||
pub fn register_datastream_publisher_codec(registry: &mut CodecRegistry) {
|
pub fn register_datastream_publisher_codec(registry: &mut CodecRegistry) {
|
||||||
registry.register::<DatastreamPublisherMsg, JsonCodec<DatastreamPublisherMsg>>(JsonCodec(
|
registry.register::<DatastreamPublisherMsg, _>(
|
||||||
PhantomData,
|
JsonCodec::<DatastreamPublisherMsg>::default(),
|
||||||
));
|
);
|
||||||
}
|
|
||||||
|
|
||||||
struct JsonCodec<M>(PhantomData<M>);
|
|
||||||
|
|
||||||
impl<M> Codec<M> for JsonCodec<M>
|
|
||||||
where
|
|
||||||
M: Serialize + DeserializeOwned + Clone + Send + Sync + 'static,
|
|
||||||
{
|
|
||||||
fn encode(&self, msg: &M) -> Result<Vec<u8>, Error> {
|
|
||||||
serde_json::to_vec(msg).map_err(|e| Error::from(format!("encode: {e}")))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn decode(&self, bytes: &[u8]) -> Result<M, Error> {
|
|
||||||
serde_json::from_slice(bytes).map_err(|e| Error::from(format!("decode: {e}")))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
//! Protocol messages for SWIM membership and the standalone gossip frames
|
//! Protocol messages for SWIM membership and the standalone gossip frames
|
||||||
//! (registry, node metadata, directory), plus their JSON codec.
|
//! (registry, node metadata, directory), plus codec registration.
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use swactor::Error;
|
use swactor::Error;
|
||||||
use swactor_transport::{Codec, CodecRegistry, NetworkMessage};
|
use swactor_transport::{CodecRegistry, JsonCodec, NetworkMessage};
|
||||||
|
|
||||||
use crate::node_metadata::NodeMetadataEntry;
|
use crate::node_metadata::NodeMetadataEntry;
|
||||||
use crate::registry::RegistryEntry;
|
use crate::registry::RegistryEntry;
|
||||||
|
|
@ -164,52 +164,21 @@ impl NetworkMessage for DirectoryGossip {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── JSON Codec ─────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
/// JSON codec for distribution protocol messages.
|
|
||||||
///
|
|
||||||
/// Using JSON for simplicity and debuggability. Can be swapped for
|
|
||||||
/// bincode/msgpack in production via the Codec trait.
|
|
||||||
pub struct JsonCodec;
|
|
||||||
|
|
||||||
macro_rules! impl_json_codec {
|
|
||||||
($ty:ty) => {
|
|
||||||
impl Codec<$ty> for JsonCodec {
|
|
||||||
fn encode(&self, msg: &$ty) -> Result<Vec<u8>, Error> {
|
|
||||||
serde_json::to_vec(msg).map_err(|e| Error::from(format!("encode: {e}")))
|
|
||||||
}
|
|
||||||
fn decode(&self, bytes: &[u8]) -> Result<$ty, Error> {
|
|
||||||
serde_json::from_slice(bytes).map_err(|e| Error::from(format!("decode: {e}")))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_json_codec!(Ping);
|
|
||||||
impl_json_codec!(Ack);
|
|
||||||
impl_json_codec!(PingReq);
|
|
||||||
impl_json_codec!(IndirectAck);
|
|
||||||
impl_json_codec!(JoinRequest);
|
|
||||||
impl_json_codec!(JoinResponse);
|
|
||||||
impl_json_codec!(RegistryGossip);
|
|
||||||
impl_json_codec!(MetadataGossip);
|
|
||||||
impl_json_codec!(DirectoryGossip);
|
|
||||||
|
|
||||||
/// Build a `CodecRegistry` with all distribution protocol messages registered.
|
/// Build a `CodecRegistry` with all distribution protocol messages registered.
|
||||||
pub fn distribution_codec_registry() -> CodecRegistry {
|
pub fn distribution_codec_registry() -> CodecRegistry {
|
||||||
let mut cr = CodecRegistry::new();
|
let mut cr = CodecRegistry::new();
|
||||||
cr.register::<Ping, _>(JsonCodec);
|
cr.register::<Ping, _>(JsonCodec::<Ping>::default());
|
||||||
cr.register::<Ack, _>(JsonCodec);
|
cr.register::<Ack, _>(JsonCodec::<Ack>::default());
|
||||||
cr.register::<PingReq, _>(JsonCodec);
|
cr.register::<PingReq, _>(JsonCodec::<PingReq>::default());
|
||||||
// §6.1 / §14.5: `IndirectAck` is folded into the shared registry so all six
|
// §6.1 / §14.5: `IndirectAck` is folded into the shared registry so all six
|
||||||
// SWIM message types decode through one uniform path; concrete drivers no
|
// SWIM message types decode through one uniform path; concrete drivers no
|
||||||
// longer need to hand-dispatch it by tag.
|
// longer need to hand-dispatch it by tag.
|
||||||
cr.register::<IndirectAck, _>(JsonCodec);
|
cr.register::<IndirectAck, _>(JsonCodec::<IndirectAck>::default());
|
||||||
cr.register::<JoinRequest, _>(JsonCodec);
|
cr.register::<JoinRequest, _>(JsonCodec::<JoinRequest>::default());
|
||||||
cr.register::<JoinResponse, _>(JsonCodec);
|
cr.register::<JoinResponse, _>(JsonCodec::<JoinResponse>::default());
|
||||||
cr.register::<RegistryGossip, _>(JsonCodec);
|
cr.register::<RegistryGossip, _>(JsonCodec::<RegistryGossip>::default());
|
||||||
cr.register::<MetadataGossip, _>(JsonCodec);
|
cr.register::<MetadataGossip, _>(JsonCodec::<MetadataGossip>::default());
|
||||||
cr.register::<DirectoryGossip, _>(JsonCodec);
|
cr.register::<DirectoryGossip, _>(JsonCodec::<DirectoryGossip>::default());
|
||||||
cr
|
cr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,31 @@
|
||||||
#![allow(dead_code)]
|
//! Driver edge/ring/stream bookkeeping.
|
||||||
|
//!
|
||||||
|
//! The driver is the node's swactor-to-iroh boundary. It tracks which edges
|
||||||
|
//! have an established send or recv pump, maps inbound uni-streams to their
|
||||||
|
//! recv rings, and emits driver lifecycle events (edge ready, stream fault,
|
||||||
|
//! pump stopped). This module is the pure state machine; the iroh stream pumps
|
||||||
|
//! themselves live in [`crate::edge_transport`].
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub(crate) struct EdgeId(pub(crate) u64);
|
pub struct EdgeId(pub u64);
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub(crate) struct RingId(pub(crate) u64);
|
pub struct RingId(pub u64);
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub(crate) struct StreamId(pub(crate) u64);
|
pub struct StreamId(pub u64);
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub(crate) enum DriverEventOut {
|
pub enum DriverEventOut {
|
||||||
DriverEdgeReady { edge_id: EdgeId },
|
DriverEdgeReady { edge_id: EdgeId },
|
||||||
StreamFault { edge_id: EdgeId },
|
StreamFault { edge_id: EdgeId },
|
||||||
PumpStopped { edge_id: EdgeId, ring_id: RingId },
|
PumpStopped { edge_id: EdgeId, ring_id: RingId },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct Driver {
|
pub struct Driver {
|
||||||
sends: BTreeMap<EdgeId, RingId>,
|
sends: BTreeMap<EdgeId, RingId>,
|
||||||
recv_specs: BTreeMap<EdgeId, RingId>,
|
recv_specs: BTreeMap<EdgeId, RingId>,
|
||||||
pending_streams: BTreeMap<EdgeId, StreamId>,
|
pending_streams: BTreeMap<EdgeId, StreamId>,
|
||||||
|
|
@ -28,7 +34,7 @@ pub(crate) struct Driver {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Driver {
|
impl Driver {
|
||||||
pub(crate) fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
sends: BTreeMap::new(),
|
sends: BTreeMap::new(),
|
||||||
recv_specs: BTreeMap::new(),
|
recv_specs: BTreeMap::new(),
|
||||||
|
|
@ -38,20 +44,20 @@ impl Driver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn establish_send(&mut self, edge_id: EdgeId, ring_id: RingId) {
|
pub fn establish_send(&mut self, edge_id: EdgeId, ring_id: RingId) {
|
||||||
self.sends.insert(edge_id, ring_id);
|
self.sends.insert(edge_id, ring_id);
|
||||||
self.events
|
self.events
|
||||||
.push(DriverEventOut::DriverEdgeReady { edge_id });
|
.push(DriverEventOut::DriverEdgeReady { edge_id });
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn establish_recv(&mut self, edge_id: EdgeId, ring_id: RingId) {
|
pub fn establish_recv(&mut self, edge_id: EdgeId, ring_id: RingId) {
|
||||||
self.recv_specs.insert(edge_id, ring_id);
|
self.recv_specs.insert(edge_id, ring_id);
|
||||||
if let Some(stream_id) = self.pending_streams.remove(&edge_id) {
|
if let Some(stream_id) = self.pending_streams.remove(&edge_id) {
|
||||||
self.spawn_recv(edge_id, stream_id);
|
self.spawn_recv(edge_id, stream_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn incoming_uni_stream(&mut self, edge_id: EdgeId, stream_id: StreamId) {
|
pub fn incoming_uni_stream(&mut self, edge_id: EdgeId, stream_id: StreamId) {
|
||||||
if self.recv_specs.contains_key(&edge_id) {
|
if self.recv_specs.contains_key(&edge_id) {
|
||||||
self.spawn_recv(edge_id, stream_id);
|
self.spawn_recv(edge_id, stream_id);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -69,11 +75,11 @@ impl Driver {
|
||||||
.push(DriverEventOut::DriverEdgeReady { edge_id });
|
.push(DriverEventOut::DriverEdgeReady { edge_id });
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn read_error(&mut self, edge_id: EdgeId) {
|
pub fn read_error(&mut self, edge_id: EdgeId) {
|
||||||
self.events.push(DriverEventOut::StreamFault { edge_id });
|
self.events.push(DriverEventOut::StreamFault { edge_id });
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn stop_edge(&mut self, edge_id: EdgeId) {
|
pub fn stop_edge(&mut self, edge_id: EdgeId) {
|
||||||
let ring_id = self
|
let ring_id = self
|
||||||
.sends
|
.sends
|
||||||
.get(&edge_id)
|
.get(&edge_id)
|
||||||
|
|
@ -89,7 +95,8 @@ impl Driver {
|
||||||
self.events
|
self.events
|
||||||
.push(DriverEventOut::PumpStopped { edge_id, ring_id });
|
.push(DriverEventOut::PumpStopped { edge_id, ring_id });
|
||||||
}
|
}
|
||||||
pub(crate) fn events(&self) -> &[DriverEventOut] {
|
|
||||||
|
pub fn events(&self) -> &[DriverEventOut] {
|
||||||
&self.events
|
&self.events
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,18 +1,29 @@
|
||||||
|
//! Endpoint advertisement masking.
|
||||||
|
//!
|
||||||
|
//! Controls how much of an iroh [`EndpointAddr`] a node advertises to peers.
|
||||||
|
//! `relay-only` strips direct IP/socket addresses so peers can only reach the
|
||||||
|
//! node via its relay URL — useful for NAT-egress-only or hidden nodes.
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use iroh::EndpointAddr;
|
use iroh::EndpointAddr;
|
||||||
|
|
||||||
pub(crate) const MVP_IROH_ENDPOINT_ADDR_MASK_ENV: &str = "MVP_IROH_ENDPOINT_ADDR_MASK";
|
/// Environment variable selecting the advertised endpoint address mask.
|
||||||
|
///
|
||||||
|
/// Recognized values: `full` (default) and `relay-only`.
|
||||||
|
pub const MVP_IROH_ENDPOINT_ADDR_MASK_ENV: &str = "MVP_IROH_ENDPOINT_ADDR_MASK";
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
||||||
pub(crate) enum EndpointAddrMask {
|
pub enum EndpointAddrMask {
|
||||||
|
/// Advertise the full endpoint address: relays and direct addresses.
|
||||||
#[default]
|
#[default]
|
||||||
Full,
|
Full,
|
||||||
|
/// Advertise relay URLs only, omitting direct socket addresses.
|
||||||
RelayOnly,
|
RelayOnly,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EndpointAddrMask {
|
impl EndpointAddrMask {
|
||||||
pub(crate) fn parse(value: &str) -> Result<Self, String> {
|
pub fn parse(value: &str) -> Result<Self, String> {
|
||||||
match value.trim().to_ascii_lowercase().as_str() {
|
match value.trim().to_ascii_lowercase().as_str() {
|
||||||
"" | "full" | "none" => Ok(Self::Full),
|
"" | "full" | "none" => Ok(Self::Full),
|
||||||
"relay-only" | "relay_only" | "relay" => Ok(Self::RelayOnly),
|
"relay-only" | "relay_only" | "relay" => Ok(Self::RelayOnly),
|
||||||
|
|
@ -22,14 +33,14 @@ impl EndpointAddrMask {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn as_str(self) -> &'static str {
|
pub fn as_str(self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Self::Full => "full",
|
Self::Full => "full",
|
||||||
Self::RelayOnly => "relay-only",
|
Self::RelayOnly => "relay-only",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn requires_relay(self) -> bool {
|
pub fn requires_relay(self) -> bool {
|
||||||
matches!(self, Self::RelayOnly)
|
matches!(self, Self::RelayOnly)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -40,7 +51,8 @@ impl fmt::Display for EndpointAddrMask {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn advertised_endpoint(
|
/// Apply `mask` to `endpoint`, returning the address to advertise to peers.
|
||||||
|
pub fn advertised_endpoint(
|
||||||
endpoint: EndpointAddr,
|
endpoint: EndpointAddr,
|
||||||
mask: EndpointAddrMask,
|
mask: EndpointAddrMask,
|
||||||
) -> Result<EndpointAddr, String> {
|
) -> Result<EndpointAddr, String> {
|
||||||
|
|
@ -5,13 +5,18 @@
|
||||||
//! wire message definitions.
|
//! wire message definitions.
|
||||||
|
|
||||||
pub mod datastream_transport;
|
pub mod datastream_transport;
|
||||||
|
pub mod driver_pumps;
|
||||||
pub mod edge_transport;
|
pub mod edge_transport;
|
||||||
|
pub mod endpoint_advertisement;
|
||||||
pub mod iroh_driver;
|
pub mod iroh_driver;
|
||||||
|
|
||||||
pub use iroh_driver::{
|
pub use iroh_driver::{
|
||||||
ConnType, DatastreamPublishHandle, IrohDriver, IrohDriverConfig, JoinPhase, JoinStatus,
|
ConnType, DatastreamPublishHandle, IrohDriver, IrohDriverConfig, JoinPhase, JoinStatus,
|
||||||
conn_type_of, discover_lan_ips,
|
conn_type_of, discover_lan_ips,
|
||||||
};
|
};
|
||||||
|
pub use endpoint_advertisement::{
|
||||||
|
MVP_IROH_ENDPOINT_ADDR_MASK_ENV, EndpointAddrMask, advertised_endpoint,
|
||||||
|
};
|
||||||
|
|
||||||
pub use edge_transport::{EDGE_ALPN, EdgeSendHandle, EdgeTransportEvent, EdgeTransportFault};
|
pub use edge_transport::{EDGE_ALPN, EdgeSendHandle, EdgeTransportEvent, EdgeTransportFault};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
//! Behavior guarantees for the `transport` module.
|
//! Behavior guarantees for endpoint advertisement masking.
|
||||||
|
|
||||||
use std::net::{Ipv4Addr, SocketAddr};
|
use std::net::{Ipv4Addr, SocketAddr};
|
||||||
|
|
||||||
use mvp_system::transport::endpoint_advertisement::{EndpointAddrMask, advertised_endpoint};
|
use iroh_driver::{EndpointAddrMask, advertised_endpoint};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn relay_only_mask_preserves_relay_urls_and_removes_direct_addresses() {
|
fn relay_only_mask_preserves_relay_urls_and_removes_direct_addresses() {
|
||||||
|
|
@ -30,7 +30,7 @@ use crate::node_provisioning::{ProviderKind, provider_kind};
|
||||||
use crate::observability::{benchmark, frame_archive::FrameArchive};
|
use crate::observability::{benchmark, frame_archive::FrameArchive};
|
||||||
use crate::orchestration::config::ResolvedVastAiConfig;
|
use crate::orchestration::config::ResolvedVastAiConfig;
|
||||||
use crate::prompt::rpc::{PromptEvent, SubmitPrompt, write_json_line};
|
use crate::prompt::rpc::{PromptEvent, SubmitPrompt, write_json_line};
|
||||||
use crate::transport::endpoint_advertisement::EndpointAddrMask;
|
use iroh_driver::EndpointAddrMask;
|
||||||
use crate::{
|
use crate::{
|
||||||
DEFAULT_PIPELINE_CACHED_MODEL_FILE, DEFAULT_PIPELINE_CACHED_MODEL_ID,
|
DEFAULT_PIPELINE_CACHED_MODEL_FILE, DEFAULT_PIPELINE_CACHED_MODEL_ID,
|
||||||
DEFAULT_PIPELINE_CACHED_MODEL_MAX_CONTEXT, DEFAULT_PIPELINE_CACHED_MODEL_REPO,
|
DEFAULT_PIPELINE_CACHED_MODEL_MAX_CONTEXT, DEFAULT_PIPELINE_CACHED_MODEL_REPO,
|
||||||
|
|
|
||||||
13
crates/mvp-system/src/codecs.rs
Normal file
13
crates/mvp-system/src/codecs.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
//! Registers wire codecs for every MVP actor message type.
|
||||||
|
//!
|
||||||
|
//! The runtime's [`CodecRegistry`](swactor_transport::CodecRegistry) needs an
|
||||||
|
//! encoder/decoder entry for each inter-node message type. This is the single
|
||||||
|
//! aggregator that wires up the node, orchestrator, prompt, and datastream
|
||||||
|
//! publisher codecs.
|
||||||
|
|
||||||
|
pub(crate) fn register_mvp_actor_codecs(registry: &mut swactor_transport::CodecRegistry) {
|
||||||
|
crate::node_actor::register_codecs(registry);
|
||||||
|
crate::orchestration::actor::register_codecs(registry);
|
||||||
|
datastream::register_datastream_publisher_codec(registry);
|
||||||
|
crate::prompt::rpc::register_codecs(registry);
|
||||||
|
}
|
||||||
|
|
@ -26,8 +26,6 @@ pub fn run_worker_node_from_env() -> std::process::ExitCode {
|
||||||
node::worker_node_runtime::run_from_env()
|
node::worker_node_runtime::run_from_env()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[path = "transport/driver_pumps.rs"]
|
|
||||||
mod driver_pumps;
|
|
||||||
#[path = "staging/gguf_common.rs"]
|
#[path = "staging/gguf_common.rs"]
|
||||||
mod gguf_common;
|
mod gguf_common;
|
||||||
#[path = "staging/gguf_shard.rs"]
|
#[path = "staging/gguf_shard.rs"]
|
||||||
|
|
@ -50,7 +48,7 @@ mod observability;
|
||||||
mod orchestration;
|
mod orchestration;
|
||||||
mod prompt;
|
mod prompt;
|
||||||
mod staging;
|
mod staging;
|
||||||
mod transport;
|
mod codecs;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use crate::run_plan;
|
||||||
use crate::staging as stage;
|
use crate::staging as stage;
|
||||||
|
|
||||||
use crate::orchestration::actor::OrchestratorMsg;
|
use crate::orchestration::actor::OrchestratorMsg;
|
||||||
use crate::transport::json_codec::JsonCodec;
|
use swactor_transport::JsonCodec;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub(crate) enum StageEdgeKindWire {
|
pub(crate) enum StageEdgeKindWire {
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ use datastream::{
|
||||||
Lifetime, NodeId, Record, StreamDescriptor, StreamId, StreamOrigin,
|
Lifetime, NodeId, Record, StreamDescriptor, StreamId, StreamOrigin,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::driver_pumps as driver_model;
|
use iroh_driver::driver_pumps as driver_model;
|
||||||
use crate::gguf_shard::{StageShardPlan, materialize_stage_shard_http, validate_stage_shard_cache};
|
use crate::gguf_shard::{StageShardPlan, materialize_stage_shard_http, validate_stage_shard_cache};
|
||||||
use crate::node_actor::{
|
use crate::node_actor::{
|
||||||
NodeAgentActor, NodeAgentMsg, NodeAgentReport, StageCommandWire, StageInboundEdgeWire,
|
NodeAgentActor, NodeAgentMsg, NodeAgentReport, StageCommandWire, StageInboundEdgeWire,
|
||||||
|
|
@ -34,10 +34,10 @@ use crate::orchestration::provider_adapters::relay::relay_runtime_config_from_en
|
||||||
use crate::prompt::rpc::{PromptEvent, TokenizerEvent};
|
use crate::prompt::rpc::{PromptEvent, TokenizerEvent};
|
||||||
use crate::run_plan::{GgufSource, TokenizerSource};
|
use crate::run_plan::{GgufSource, TokenizerSource};
|
||||||
use crate::staging::control as stage;
|
use crate::staging::control as stage;
|
||||||
use crate::transport::endpoint_advertisement::{
|
use iroh_driver::{
|
||||||
EndpointAddrMask, MVP_IROH_ENDPOINT_ADDR_MASK_ENV, advertised_endpoint,
|
EndpointAddrMask, MVP_IROH_ENDPOINT_ADDR_MASK_ENV, advertised_endpoint,
|
||||||
};
|
};
|
||||||
use crate::transport::register_mvp_actor_codecs;
|
use crate::codecs::register_mvp_actor_codecs;
|
||||||
use data_plane::arena;
|
use data_plane::arena;
|
||||||
use data_plane::edge_lifecycle as edge;
|
use data_plane::edge_lifecycle as edge;
|
||||||
use data_plane::ingress;
|
use data_plane::ingress;
|
||||||
|
|
@ -1630,12 +1630,13 @@ fn run_stage_shard_fetcher() -> Result<(), String> {
|
||||||
|
|
||||||
fn run() -> Result<(), String> {
|
fn run() -> Result<(), String> {
|
||||||
let config = DeploymentConfig::from_env()?;
|
let config = DeploymentConfig::from_env()?;
|
||||||
emit_stdio_node_event(
|
let boot = |phase: &str, status: &str, detail: Value| {
|
||||||
&config,
|
emit_stdio_node_event(&config, NODE_BOOTSTRAP_CHANNEL, phase, status, detail)
|
||||||
NODE_BOOTSTRAP_CHANNEL,
|
};
|
||||||
"config",
|
let worker_evt = |phase: &str, status: &str, detail: Value| {
|
||||||
"ready",
|
emit_stdio_node_event(&config, NODE_WORKER_CHANNEL, phase, status, detail)
|
||||||
json!({
|
};
|
||||||
|
boot("config", "ready", json!({
|
||||||
"worker_script":&config.worker_script,
|
"worker_script":&config.worker_script,
|
||||||
"device":&config.device,
|
"device":&config.device,
|
||||||
"model_id":&config.model_id,
|
"model_id":&config.model_id,
|
||||||
|
|
@ -1645,35 +1646,16 @@ fn run() -> Result<(), String> {
|
||||||
"arena_bytes":config.arena_bytes,
|
"arena_bytes":config.arena_bytes,
|
||||||
"arena_alignment":config.arena_alignment,
|
"arena_alignment":config.arena_alignment,
|
||||||
"debug_join_socket":config.debug_join_socket.as_deref().unwrap_or("disabled"),
|
"debug_join_socket":config.debug_join_socket.as_deref().unwrap_or("disabled"),
|
||||||
}),
|
}))?;
|
||||||
)?;
|
boot("process", "started", json!({"binary":"mvp-worker-node","pid":std::process::id()}))?;
|
||||||
emit_stdio_node_event(
|
|
||||||
&config,
|
|
||||||
NODE_BOOTSTRAP_CHANNEL,
|
|
||||||
"process",
|
|
||||||
"started",
|
|
||||||
json!({"binary":"mvp-worker-node","pid":std::process::id()}),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let tokio = match tokio::runtime::Runtime::new() {
|
let tokio = match tokio::runtime::Runtime::new() {
|
||||||
Ok(runtime) => {
|
Ok(runtime) => {
|
||||||
emit_stdio_node_event(
|
boot("tokio_runtime", "ready", json!({"runtime":"tokio"}))?;
|
||||||
&config,
|
|
||||||
NODE_BOOTSTRAP_CHANNEL,
|
|
||||||
"tokio_runtime",
|
|
||||||
"ready",
|
|
||||||
json!({"runtime":"tokio"}),
|
|
||||||
)?;
|
|
||||||
runtime
|
runtime
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
emit_stdio_node_event(
|
boot("tokio_runtime", "failed", json!({"error":error.to_string()}))?;
|
||||||
&config,
|
|
||||||
NODE_BOOTSTRAP_CHANNEL,
|
|
||||||
"tokio_runtime",
|
|
||||||
"failed",
|
|
||||||
json!({"error":error.to_string()}),
|
|
||||||
)?;
|
|
||||||
return Err(format!("tokio runtime: {error}"));
|
return Err(format!("tokio runtime: {error}"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -1689,42 +1671,18 @@ fn run() -> Result<(), String> {
|
||||||
) {
|
) {
|
||||||
Ok(driver) => driver,
|
Ok(driver) => driver,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
emit_stdio_node_event(
|
boot("iroh_driver", "failed", json!({"error":error.to_string()}))?;
|
||||||
&config,
|
|
||||||
NODE_BOOTSTRAP_CHANNEL,
|
|
||||||
"iroh_driver",
|
|
||||||
"failed",
|
|
||||||
json!({"error":error.to_string()}),
|
|
||||||
)?;
|
|
||||||
return Err(format!("create iroh driver: {error}"));
|
return Err(format!("create iroh driver: {error}"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let advertised_self_endpoint =
|
let advertised_self_endpoint =
|
||||||
advertised_endpoint(driver.endpoint_addr(), config.endpoint_addr_mask)?;
|
advertised_endpoint(driver.endpoint_addr(), config.endpoint_addr_mask)?;
|
||||||
emit_stdio_node_event(
|
boot("iroh_driver", "ready", json!({"endpoint":advertised_self_endpoint.clone(),"has_relay":advertised_self_endpoint.relay_urls().next().is_some(),"direct_addr_count":advertised_self_endpoint.ip_addrs().count(),"relay_mode":format!("{:?}", config.relay_mode),"endpoint_addr_mask":config.endpoint_addr_mask.as_str()}))?;
|
||||||
&config,
|
|
||||||
NODE_BOOTSTRAP_CHANNEL,
|
|
||||||
"iroh_driver",
|
|
||||||
"ready",
|
|
||||||
json!({"endpoint":advertised_self_endpoint.clone(),"has_relay":advertised_self_endpoint.relay_urls().next().is_some(),"direct_addr_count":advertised_self_endpoint.ip_addrs().count(),"relay_mode":format!("{:?}", config.relay_mode),"endpoint_addr_mask":config.endpoint_addr_mask.as_str()}),
|
|
||||||
)?;
|
|
||||||
if let Some(coordinator) = &config.coordinator_endpoint {
|
if let Some(coordinator) = &config.coordinator_endpoint {
|
||||||
driver.join(std::slice::from_ref(coordinator));
|
driver.join(std::slice::from_ref(coordinator));
|
||||||
emit_stdio_node_event(
|
boot("coordinator_join", "started", json!({"endpoint":coordinator,"has_relay":coordinator.relay_urls().next().is_some(),"direct_addr_count":coordinator.ip_addrs().count()}))?;
|
||||||
&config,
|
|
||||||
NODE_BOOTSTRAP_CHANNEL,
|
|
||||||
"coordinator_join",
|
|
||||||
"started",
|
|
||||||
json!({"endpoint":coordinator,"has_relay":coordinator.relay_urls().next().is_some(),"direct_addr_count":coordinator.ip_addrs().count()}),
|
|
||||||
)?;
|
|
||||||
} else {
|
} else {
|
||||||
emit_stdio_node_event(
|
boot("coordinator_join", "skipped", json!({"reason":"MVP_COORDINATOR_ENDPOINT not set","mode":"standalone"}))?;
|
||||||
&config,
|
|
||||||
NODE_BOOTSTRAP_CHANNEL,
|
|
||||||
"coordinator_join",
|
|
||||||
"skipped",
|
|
||||||
json!({"reason":"MVP_COORDINATOR_ENDPOINT not set","mode":"standalone"}),
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let stack = DistributionRuntimeStack::new_with_codecs(
|
let stack = DistributionRuntimeStack::new_with_codecs(
|
||||||
|
|
@ -1735,20 +1693,8 @@ fn run() -> Result<(), String> {
|
||||||
datastream::wire::register_datastream_codec(registry);
|
datastream::wire::register_datastream_codec(registry);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
emit_stdio_node_event(
|
boot("distribution_stack", "ready", json!({"actors":"initialized","route_view":"initialized","swim":"initialized","outbox":"initialized"}))?;
|
||||||
&config,
|
boot("codecs", "ready", json!({"registered":["node_agent","orchestrator","provisioner","prompt_rpc","datastream"]}))?;
|
||||||
NODE_BOOTSTRAP_CHANNEL,
|
|
||||||
"distribution_stack",
|
|
||||||
"ready",
|
|
||||||
json!({"actors":"initialized","route_view":"initialized","swim":"initialized","outbox":"initialized"}),
|
|
||||||
)?;
|
|
||||||
emit_stdio_node_event(
|
|
||||||
&config,
|
|
||||||
NODE_BOOTSTRAP_CHANNEL,
|
|
||||||
"codecs",
|
|
||||||
"ready",
|
|
||||||
json!({"registered":["node_agent","orchestrator","provisioner","prompt_rpc","datastream"]}),
|
|
||||||
)?;
|
|
||||||
driver.enable_actor_bridge(
|
driver.enable_actor_bridge(
|
||||||
stack.runtime.clone(),
|
stack.runtime.clone(),
|
||||||
stack.codec.clone(),
|
stack.codec.clone(),
|
||||||
|
|
@ -1757,13 +1703,7 @@ fn run() -> Result<(), String> {
|
||||||
stack.relay_mirror.clone(),
|
stack.relay_mirror.clone(),
|
||||||
stack.route_view.clone(),
|
stack.route_view.clone(),
|
||||||
);
|
);
|
||||||
emit_stdio_node_event(
|
boot("actor_bridge", "ready", json!({"transport":"iroh","routes":"attached"}))?;
|
||||||
&config,
|
|
||||||
NODE_BOOTSTRAP_CHANNEL,
|
|
||||||
"actor_bridge",
|
|
||||||
"ready",
|
|
||||||
json!({"transport":"iroh","routes":"attached"}),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let arena_manager = match arena::ArenaManager::boot(arena::ArenaConfig {
|
let arena_manager = match arena::ArenaManager::boot(arena::ArenaConfig {
|
||||||
node_id: arena::NodeId(config.logical_node_id),
|
node_id: arena::NodeId(config.logical_node_id),
|
||||||
|
|
@ -1771,26 +1711,14 @@ fn run() -> Result<(), String> {
|
||||||
base_alignment: config.arena_alignment,
|
base_alignment: config.arena_alignment,
|
||||||
}) {
|
}) {
|
||||||
Ok(manager) => {
|
Ok(manager) => {
|
||||||
emit_stdio_node_event(
|
boot("arena_manager", "ready", json!({
|
||||||
&config,
|
|
||||||
NODE_BOOTSTRAP_CHANNEL,
|
|
||||||
"arena_manager",
|
|
||||||
"ready",
|
|
||||||
json!({
|
|
||||||
"arena_bytes":config.arena_bytes,
|
"arena_bytes":config.arena_bytes,
|
||||||
"arena_alignment":config.arena_alignment,
|
"arena_alignment":config.arena_alignment,
|
||||||
}),
|
}))?;
|
||||||
)?;
|
|
||||||
Arc::new(Mutex::new(manager))
|
Arc::new(Mutex::new(manager))
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
emit_stdio_node_event(
|
boot("arena_manager", "failed", json!({"error":format!("{error:?}")}))?;
|
||||||
&config,
|
|
||||||
NODE_BOOTSTRAP_CHANNEL,
|
|
||||||
"arena_manager",
|
|
||||||
"failed",
|
|
||||||
json!({"error":format!("{error:?}")}),
|
|
||||||
)?;
|
|
||||||
return Err(format!("boot arena manager: {error:?}"));
|
return Err(format!("boot arena manager: {error:?}"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -1917,23 +1845,11 @@ fn run() -> Result<(), String> {
|
||||||
|
|
||||||
let reports = match stack.runtime.new_inbox::<NodeAgentReport>() {
|
let reports = match stack.runtime.new_inbox::<NodeAgentReport>() {
|
||||||
Ok(inbox) => {
|
Ok(inbox) => {
|
||||||
emit_stdio_node_event(
|
boot("node_report_inbox", "ready", json!({"actor":inbox.addr()}))?;
|
||||||
&config,
|
|
||||||
NODE_BOOTSTRAP_CHANNEL,
|
|
||||||
"node_report_inbox",
|
|
||||||
"ready",
|
|
||||||
json!({"actor":inbox.addr()}),
|
|
||||||
)?;
|
|
||||||
inbox
|
inbox
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
emit_stdio_node_event(
|
boot("node_report_inbox", "failed", json!({"error":error.to_string()}))?;
|
||||||
&config,
|
|
||||||
NODE_BOOTSTRAP_CHANNEL,
|
|
||||||
"node_report_inbox",
|
|
||||||
"failed",
|
|
||||||
json!({"error":error.to_string()}),
|
|
||||||
)?;
|
|
||||||
return Err(format!("node report inbox: {error}"));
|
return Err(format!("node report inbox: {error}"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -1941,13 +1857,7 @@ fn run() -> Result<(), String> {
|
||||||
"MVP_ORCHESTRATOR_ACTOR is required for runtime readiness signaling".to_owned()
|
"MVP_ORCHESTRATOR_ACTOR is required for runtime readiness signaling".to_owned()
|
||||||
})?;
|
})?;
|
||||||
let orchestrator_source = "env";
|
let orchestrator_source = "env";
|
||||||
emit_stdio_node_event(
|
boot("orchestrator_actor", "ready", json!({"actor":orchestrator,"source":orchestrator_source}))?;
|
||||||
&config,
|
|
||||||
NODE_BOOTSTRAP_CHANNEL,
|
|
||||||
"orchestrator_actor",
|
|
||||||
"ready",
|
|
||||||
json!({"actor":orchestrator,"source":orchestrator_source}),
|
|
||||||
)?;
|
|
||||||
let node_agent = NodeAgentActor::new(
|
let node_agent = NodeAgentActor::new(
|
||||||
stage::NodeId(config.logical_node_id),
|
stage::NodeId(config.logical_node_id),
|
||||||
orchestrator,
|
orchestrator,
|
||||||
|
|
@ -1955,59 +1865,29 @@ fn run() -> Result<(), String> {
|
||||||
);
|
);
|
||||||
let node_actor = match stack.runtime.spawn(node_agent) {
|
let node_actor = match stack.runtime.spawn(node_agent) {
|
||||||
Ok(actor) => {
|
Ok(actor) => {
|
||||||
emit_stdio_node_event(
|
boot("node_agent", "ready", json!({"node_actor":actor,"source":"generated"}))?;
|
||||||
&config,
|
|
||||||
NODE_BOOTSTRAP_CHANNEL,
|
|
||||||
"node_agent",
|
|
||||||
"ready",
|
|
||||||
json!({"node_actor":actor,"source":"generated"}),
|
|
||||||
)?;
|
|
||||||
actor
|
actor
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
emit_stdio_node_event(
|
boot("node_agent", "failed", json!({"error":error.to_string(),"source":"generated"}))?;
|
||||||
&config,
|
|
||||||
NODE_BOOTSTRAP_CHANNEL,
|
|
||||||
"node_agent",
|
|
||||||
"failed",
|
|
||||||
json!({"error":error.to_string(),"source":"generated"}),
|
|
||||||
)?;
|
|
||||||
return Err(format!("spawn node agent: {error}"));
|
return Err(format!("spawn node agent: {error}"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
stack.register_local_actor(driver.register_actor(node_actor, 1));
|
stack.register_local_actor(driver.register_actor(node_actor, 1));
|
||||||
emit_stdio_node_event(
|
boot("node_actor_registration", "ready", json!({"node_actor":node_actor,"network_reachable":true}))?;
|
||||||
&config,
|
|
||||||
NODE_BOOTSTRAP_CHANNEL,
|
|
||||||
"node_actor_registration",
|
|
||||||
"ready",
|
|
||||||
json!({"node_actor":node_actor,"network_reachable":true}),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
emit_stdio_node_event(
|
worker_evt("worker_process", "started", json!({
|
||||||
&config,
|
|
||||||
NODE_WORKER_CHANNEL,
|
|
||||||
"worker_process",
|
|
||||||
"started",
|
|
||||||
json!({
|
|
||||||
"program":"python3",
|
"program":"python3",
|
||||||
"script":&config.worker_script,
|
"script":&config.worker_script,
|
||||||
"device":&config.device,
|
"device":&config.device,
|
||||||
"stdin":"piped",
|
"stdin":"piped",
|
||||||
"stdout":"piped",
|
"stdout":"piped",
|
||||||
"stderr":"piped",
|
"stderr":"piped",
|
||||||
}),
|
}))?;
|
||||||
)?;
|
|
||||||
let mut worker = match TinygradWorker::spawn(&config, arena_fd) {
|
let mut worker = match TinygradWorker::spawn(&config, arena_fd) {
|
||||||
Ok(worker) => worker,
|
Ok(worker) => worker,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
emit_stdio_node_event(
|
worker_evt("worker_process", "failed", json!({"error":error}))?;
|
||||||
&config,
|
|
||||||
NODE_WORKER_CHANNEL,
|
|
||||||
"worker_process",
|
|
||||||
"failed",
|
|
||||||
json!({"error":error}),
|
|
||||||
)?;
|
|
||||||
return Err(error);
|
return Err(error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -2019,30 +1899,12 @@ fn run() -> Result<(), String> {
|
||||||
sampler_health_context,
|
sampler_health_context,
|
||||||
vec![std::process::id(), worker.pid()],
|
vec![std::process::id(), worker.pid()],
|
||||||
);
|
);
|
||||||
emit_stdio_node_event(
|
worker_evt("worker_initialize", "started", json!({"command":"InitializeWorker","helper_abi_version":1,"device":&config.device}))?;
|
||||||
&config,
|
|
||||||
NODE_WORKER_CHANNEL,
|
|
||||||
"worker_initialize",
|
|
||||||
"started",
|
|
||||||
json!({"command":"InitializeWorker","helper_abi_version":1,"device":&config.device}),
|
|
||||||
)?;
|
|
||||||
let mut initial_pump = || {};
|
let mut initial_pump = || {};
|
||||||
match worker.initialize(&config.device, &config, &mut datastream, &mut initial_pump) {
|
match worker.initialize(&config.device, &config, &mut datastream, &mut initial_pump) {
|
||||||
Ok(()) => emit_stdio_node_event(
|
Ok(()) => worker_evt("worker_initialize", "ready", json!({"worker_event_type":"WorkerReady"}))?,
|
||||||
&config,
|
|
||||||
NODE_WORKER_CHANNEL,
|
|
||||||
"worker_initialize",
|
|
||||||
"ready",
|
|
||||||
json!({"worker_event_type":"WorkerReady"}),
|
|
||||||
)?,
|
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
emit_stdio_node_event(
|
worker_evt("worker_initialize", "failed", json!({"error":error}))?;
|
||||||
&config,
|
|
||||||
NODE_WORKER_CHANNEL,
|
|
||||||
"worker_initialize",
|
|
||||||
"failed",
|
|
||||||
json!({"error":error}),
|
|
||||||
)?;
|
|
||||||
return Err(error);
|
return Err(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2063,19 +1925,13 @@ fn run() -> Result<(), String> {
|
||||||
"logical_node_id": config.logical_node_id,
|
"logical_node_id": config.logical_node_id,
|
||||||
"stage_index": config.stage_index,
|
"stage_index": config.stage_index,
|
||||||
});
|
});
|
||||||
emit_stdio_node_event(
|
boot("runtime_ready_local", "ready", json!({
|
||||||
&config,
|
|
||||||
NODE_BOOTSTRAP_CHANNEL,
|
|
||||||
"runtime_ready_local",
|
|
||||||
"ready",
|
|
||||||
json!({
|
|
||||||
"endpoint":advertised_self_endpoint.clone(),
|
"endpoint":advertised_self_endpoint.clone(),
|
||||||
"node_actor":node_actor,
|
"node_actor":node_actor,
|
||||||
"logical_node_id":config.logical_node_id,
|
"logical_node_id":config.logical_node_id,
|
||||||
"stage_index":config.stage_index,
|
"stage_index":config.stage_index,
|
||||||
"readiness_id":pending_runtime_ready.readiness_id,
|
"readiness_id":pending_runtime_ready.readiness_id,
|
||||||
}),
|
}))?;
|
||||||
)?;
|
|
||||||
|
|
||||||
if let Some(prompt) = &config.self_test_prompt {
|
if let Some(prompt) = &config.self_test_prompt {
|
||||||
run_self_test(
|
run_self_test(
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use swactor_transport::{CodecRegistry, NetworkMessage};
|
||||||
|
|
||||||
use crate::run_fsm as core;
|
use crate::run_fsm as core;
|
||||||
|
|
||||||
use crate::transport::json_codec::JsonCodec;
|
use swactor_transport::JsonCodec;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub(crate) struct StageRefWire {
|
pub(crate) struct StageRefWire {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ use crate::observability::dashboard_view::MvpClusterDashboardView;
|
||||||
use crate::observability::{benchmark, frame_archive::FrameArchive};
|
use crate::observability::{benchmark, frame_archive::FrameArchive};
|
||||||
use crate::orchestration::actor::{OrchestratorActor, OrchestratorReport};
|
use crate::orchestration::actor::{OrchestratorActor, OrchestratorReport};
|
||||||
use crate::orchestration::config::{DEFAULT_CONFIG_PATH, TomlConfigOverlay};
|
use crate::orchestration::config::{DEFAULT_CONFIG_PATH, TomlConfigOverlay};
|
||||||
use crate::transport::register_mvp_actor_codecs;
|
use crate::codecs::register_mvp_actor_codecs;
|
||||||
const PROVIDER_START_MAX_ATTEMPTS: usize = 4;
|
const PROVIDER_START_MAX_ATTEMPTS: usize = 4;
|
||||||
|
|
||||||
use crate::gguf_shard::{StageShardPlan, plan_stage_shard};
|
use crate::gguf_shard::{StageShardPlan, plan_stage_shard};
|
||||||
|
|
@ -48,7 +48,7 @@ use crate::provisioning::{
|
||||||
};
|
};
|
||||||
use crate::run_fsm::{RunConfig, RunId};
|
use crate::run_fsm::{RunConfig, RunId};
|
||||||
use crate::run_plan::{self, GgufSource, TokenizerSource};
|
use crate::run_plan::{self, GgufSource, TokenizerSource};
|
||||||
use crate::transport::endpoint_advertisement::{
|
use iroh_driver::{
|
||||||
EndpointAddrMask, MVP_IROH_ENDPOINT_ADDR_MASK_ENV, advertised_endpoint,
|
EndpointAddrMask, MVP_IROH_ENDPOINT_ADDR_MASK_ENV, advertised_endpoint,
|
||||||
};
|
};
|
||||||
use data_plane::object_record as ingress;
|
use data_plane::object_record as ingress;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use std::io::{BufRead, Write};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use swactor_transport::{CodecRegistry, NetworkMessage};
|
use swactor_transport::{CodecRegistry, NetworkMessage};
|
||||||
|
|
||||||
use crate::transport::json_codec::JsonCodec;
|
use swactor_transport::JsonCodec;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub(crate) struct SubmitPrompt {
|
pub(crate) struct SubmitPrompt {
|
||||||
|
|
|
||||||
|
|
@ -5,4 +5,3 @@ mod observability_guarantees;
|
||||||
mod orchestration_guarantees;
|
mod orchestration_guarantees;
|
||||||
mod prompt_guarantees;
|
mod prompt_guarantees;
|
||||||
mod staging_guarantees;
|
mod staging_guarantees;
|
||||||
mod transport_guarantees;
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
//! MVP edge transport public surface.
|
|
||||||
|
|
||||||
pub(crate) fn register_mvp_actor_codecs(registry: &mut swactor_transport::CodecRegistry) {
|
|
||||||
crate::node_actor::register_codecs(registry);
|
|
||||||
crate::orchestration::actor::register_codecs(registry);
|
|
||||||
datastream::register_datastream_publisher_codec(registry);
|
|
||||||
crate::prompt::rpc::register_codecs(registry);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) mod endpoint_advertisement;
|
|
||||||
pub(crate) mod json_codec;
|
|
||||||
|
|
@ -1,11 +1,22 @@
|
||||||
|
//! Generic JSON codec for serde message types.
|
||||||
|
//!
|
||||||
|
//! [`JsonCodec<M>`] is the out-of-the-box [`Codec`] for messages that are
|
||||||
|
//! [`Serialize`] + [`DeserializeOwned`]. Use a custom codec when a wire format
|
||||||
|
//! needs schema stability or compactness beyond JSON.
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
use swactor::Error;
|
use swactor::Error;
|
||||||
use swactor_transport::Codec;
|
|
||||||
|
|
||||||
pub(crate) struct JsonCodec<M>(PhantomData<M>);
|
use crate::codec::Codec;
|
||||||
|
|
||||||
|
/// JSON codec for message type `M`.
|
||||||
|
///
|
||||||
|
/// Implements [`Codec<M>`] via `serde_json`. Construct with
|
||||||
|
/// [`JsonCodec::default`] / `JsonCodec::<M>::default()`.
|
||||||
|
pub struct JsonCodec<M>(PhantomData<M>);
|
||||||
|
|
||||||
impl<M> Default for JsonCodec<M> {
|
impl<M> Default for JsonCodec<M> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
|
@ -8,9 +8,11 @@
|
||||||
pub mod codec;
|
pub mod codec;
|
||||||
pub mod crypto;
|
pub mod crypto;
|
||||||
pub mod identity;
|
pub mod identity;
|
||||||
|
pub mod json_codec;
|
||||||
pub mod transport;
|
pub mod transport;
|
||||||
|
|
||||||
pub use codec::{
|
pub use codec::{
|
||||||
hex_decode, hex_encode, Codec, CodecRegistry, NetworkMessage, NodeId, WireEnvelope,
|
hex_decode, hex_encode, Codec, CodecRegistry, NetworkMessage, NodeId, WireEnvelope,
|
||||||
};
|
};
|
||||||
|
pub use json_codec::JsonCodec;
|
||||||
pub use transport::{CodecRemoteSink, InMemoryTransport, Transport, TransportRouter};
|
pub use transport::{CodecRemoteSink, InMemoryTransport, Transport, TransportRouter};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue