| use std::collections::HashMap; |
| use std::path::PathBuf; |
| use std::sync::Arc; |
| use std::time::Duration; |
|
|
| use codex_http_client::HttpClientFactory; |
| use futures::future::BoxFuture; |
| use http::HeaderMap; |
| use tokio::sync::watch; |
|
|
| use crate::ExecServerError; |
| use crate::HttpRequestParams; |
| use crate::HttpRequestResponse; |
| use crate::HttpResponseBodyStream; |
| use crate::NoiseChannelIdentity; |
| use crate::NoiseChannelPublicKey; |
|
|
| pub(crate) const DEFAULT_REMOTE_EXEC_SERVER_CONNECT_TIMEOUT: Duration = Duration::from_secs(10); |
| pub(crate) const DEFAULT_REMOTE_EXEC_SERVER_INITIALIZE_TIMEOUT: Duration = Duration::from_secs(10); |
|
|
| |
| #[derive(Debug, Clone, PartialEq, Eq)] |
| pub struct ExecServerClientConnectOptions { |
| pub client_name: String, |
| pub initialize_timeout: Duration, |
| pub resume_session_id: Option<String>, |
| } |
|
|
| |
| #[derive(Debug, Clone, PartialEq, Eq)] |
| pub struct RemoteExecServerConnectArgs { |
| pub websocket_url: String, |
| pub client_name: String, |
| pub connect_timeout: Duration, |
| pub initialize_timeout: Duration, |
| pub resume_session_id: Option<String>, |
| pub http_client_factory: HttpClientFactory, |
| } |
|
|
| |
| |
| |
| |
| |
| |
| pub struct NoiseRendezvousConnectBundle { |
| pub websocket_url: String, |
| pub environment_id: String, |
| pub executor_registration_id: String, |
| pub executor_public_key: NoiseChannelPublicKey, |
| pub harness_key_authorization: String, |
| } |
|
|
| |
| |
| |
| |
| |
| pub struct NoiseRendezvousConnectArgs { |
| pub bundle: NoiseRendezvousConnectBundle, |
| pub harness_identity: NoiseChannelIdentity, |
| pub client_name: String, |
| pub connect_timeout: Duration, |
| pub initialize_timeout: Duration, |
| pub resume_session_id: Option<String>, |
| pub http_client_factory: HttpClientFactory, |
| } |
|
|
| |
| pub trait NoiseRendezvousConnectProvider: Send + Sync { |
| |
| fn connect_bundle( |
| &self, |
| harness_public_key: NoiseChannelPublicKey, |
| ) -> BoxFuture<'_, Result<NoiseRendezvousConnectBundle, ExecServerError>>; |
| } |
|
|
| |
| #[derive(Debug, Clone, PartialEq, Eq)] |
| pub(crate) struct StdioExecServerConnectArgs { |
| pub command: StdioExecServerCommand, |
| pub client_name: String, |
| pub initialize_timeout: Duration, |
| pub resume_session_id: Option<String>, |
| } |
|
|
| |
| #[derive(Debug, Clone, PartialEq, Eq)] |
| pub(crate) struct StdioExecServerCommand { |
| pub program: String, |
| pub args: Vec<String>, |
| pub env: HashMap<String, String>, |
| pub cwd: Option<PathBuf>, |
| } |
|
|
| pub(crate) type DeferredEnvironmentReadiness = watch::Receiver<Option<Result<(), String>>>; |
|
|
| #[derive(Clone)] |
| pub(crate) struct Deferred<T> { |
| pub readiness: DeferredEnvironmentReadiness, |
| pub transport: T, |
| } |
|
|
| |
| #[derive(Clone)] |
| pub(crate) enum ExecServerTransportParams { |
| Deferred(Box<Deferred<ExecServerTransportParams>>), |
| WebSocketUrl { |
| websocket_url: String, |
| connect_timeout: Duration, |
| initialize_timeout: Duration, |
| http_headers: HeaderMap, |
| }, |
| NoiseRendezvous { |
| provider: Arc<dyn NoiseRendezvousConnectProvider>, |
| identity: NoiseChannelIdentity, |
| }, |
| #[allow(dead_code)] |
| StdioCommand { |
| command: StdioExecServerCommand, |
| initialize_timeout: Duration, |
| }, |
| } |
|
|
| impl std::fmt::Debug for ExecServerTransportParams { |
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| match self { |
| Self::Deferred(deferred) => f |
| .debug_struct("Deferred") |
| .field("transport", &deferred.transport) |
| .finish_non_exhaustive(), |
| Self::WebSocketUrl { |
| websocket_url, |
| connect_timeout, |
| initialize_timeout, |
| .. |
| } => f |
| .debug_struct("WebSocketUrl") |
| .field("websocket_url", websocket_url) |
| .field("connect_timeout", connect_timeout) |
| .field("initialize_timeout", initialize_timeout) |
| .field("http_headers", &"<redacted>") |
| .finish(), |
| Self::NoiseRendezvous { .. } => { |
| f.debug_struct("NoiseRendezvous").finish_non_exhaustive() |
| } |
| Self::StdioCommand { |
| command, |
| initialize_timeout, |
| } => f |
| .debug_struct("StdioCommand") |
| .field("command", command) |
| .field("initialize_timeout", initialize_timeout) |
| .finish(), |
| } |
| } |
| } |
|
|
| impl ExecServerTransportParams { |
| pub(crate) fn websocket_url(websocket_url: String, connect_timeout: Duration) -> Self { |
| Self::WebSocketUrl { |
| websocket_url, |
| connect_timeout, |
| initialize_timeout: DEFAULT_REMOTE_EXEC_SERVER_INITIALIZE_TIMEOUT, |
| http_headers: HeaderMap::new(), |
| } |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| pub trait HttpClient: Send + Sync { |
| |
| fn http_request( |
| &self, |
| params: HttpRequestParams, |
| ) -> BoxFuture<'_, Result<HttpRequestResponse, ExecServerError>>; |
|
|
| |
| fn http_request_stream( |
| &self, |
| params: HttpRequestParams, |
| ) -> BoxFuture<'_, Result<(HttpRequestResponse, HttpResponseBodyStream), ExecServerError>>; |
| } |
|
|