Skip to main content

datum_agent/dcp/
mod.rs

1//! Datum Control Protocol (DCP) server and client.
2//!
3//! DCP is a small prost protocol over length-prefixed TCP or QUIC streams. It is
4//! intentionally local to `datum-agent`: the registry remains the control-plane
5//! owner, while DCP is the management transport used by the upcoming CLI/TUI and
6//! cluster work.
7
8pub mod client;
9pub mod proto;
10pub mod server;
11
12mod frame;
13
14use thiserror::Error;
15
16pub use client::{DcpClient, EventSubscription, MetricSubscription};
17pub use proto::{
18    Auth, ClientKind, DCP_PROTOCOL_MAJOR, DCP_PROTOCOL_VERSION, DrainJob, GetConfig, Hello,
19    JobStatusRequest, ListJobs, PutConfig, Request, Response, ResponseStatus, RestartJob, StartJob,
20    StopJob, SubscribeEvents, SubscribeMetrics,
21};
22pub use server::{
23    DcpJobFactories, DcpQuicServerConfig, DcpServer, DcpServerConfig, DcpServerHandle,
24    DcpTcpServerConfig,
25};
26
27/// Result type used by DCP APIs.
28pub type DcpResult<T> = Result<T, DcpError>;
29
30/// Errors returned by DCP clients, servers, and frame codecs.
31#[derive(Debug, Error)]
32pub enum DcpError {
33    #[error("DCP connection closed")]
34    Closed,
35    #[error("DCP protocol error: {0}")]
36    Protocol(String),
37    #[error("DCP response {status:?}: {message}")]
38    Response {
39        status: ResponseStatus,
40        message: String,
41    },
42    #[error("DCP IO error: {0}")]
43    Io(#[from] std::io::Error),
44    #[error("DCP encode error: {0}")]
45    Encode(#[from] prost::EncodeError),
46    #[error("DCP decode error: {0}")]
47    Decode(#[from] prost::DecodeError),
48    #[error("DCP agent error: {0}")]
49    Agent(#[from] crate::AgentError),
50    #[error("DCP stream error: {0}")]
51    Stream(#[from] datum::StreamError),
52    #[error("DCP task failed: {0}")]
53    Join(#[from] tokio::task::JoinError),
54}
55
56impl DcpError {
57    pub(crate) fn response(status: ResponseStatus, message: impl Into<String>) -> Self {
58        Self::Response {
59            status,
60            message: message.into(),
61        }
62    }
63}