1use std::collections::HashMap;
2use std::path::PathBuf;
3use std::sync::Arc;
4use std::time::Duration;
5
6use futures::future::BoxFuture;
7use futures::future::Shared;
8use tokio::sync::oneshot;
9
10use crate::ExecServerError;
11use crate::HttpRequestParams;
12use crate::HttpRequestResponse;
13use crate::HttpResponseBodyStream;
14use crate::NoiseChannelIdentity;
15use crate::NoiseChannelPublicKey;
16
17pub(crate) const DEFAULT_REMOTE_EXEC_SERVER_CONNECT_TIMEOUT: Duration = Duration::from_secs(10);
18pub(crate) const DEFAULT_REMOTE_EXEC_SERVER_INITIALIZE_TIMEOUT: Duration = Duration::from_secs(10);
19
20#[derive(Debug, Clone, PartialEq, Eq)]
22pub struct ExecServerClientConnectOptions {
23 pub client_name: String,
24 pub initialize_timeout: Duration,
25 pub resume_session_id: Option<String>,
26}
27
28#[derive(Debug, Clone, PartialEq, Eq)]
30pub struct RemoteExecServerConnectArgs {
31 pub websocket_url: String,
32 pub client_name: String,
33 pub connect_timeout: Duration,
34 pub initialize_timeout: Duration,
35 pub resume_session_id: Option<String>,
36}
37
38pub struct NoiseRendezvousConnectBundle {
45 pub websocket_url: String,
46 pub environment_id: String,
47 pub executor_registration_id: String,
48 pub executor_public_key: NoiseChannelPublicKey,
49 pub harness_key_authorization: String,
50}
51
52pub struct NoiseRendezvousConnectArgs {
58 pub bundle: NoiseRendezvousConnectBundle,
59 pub harness_identity: NoiseChannelIdentity,
60 pub client_name: String,
61 pub connect_timeout: Duration,
62 pub initialize_timeout: Duration,
63 pub resume_session_id: Option<String>,
64}
65
66pub trait NoiseRendezvousConnectProvider: Send + Sync {
68 fn connect_bundle(
70 &self,
71 harness_public_key: NoiseChannelPublicKey,
72 ) -> BoxFuture<'_, Result<NoiseRendezvousConnectBundle, ExecServerError>>;
73}
74
75#[derive(Debug, Clone, PartialEq, Eq)]
77pub(crate) struct StdioExecServerConnectArgs {
78 pub command: StdioExecServerCommand,
79 pub client_name: String,
80 pub initialize_timeout: Duration,
81 pub resume_session_id: Option<String>,
82}
83
84#[derive(Debug, Clone, PartialEq, Eq)]
86pub(crate) struct StdioExecServerCommand {
87 pub program: String,
88 pub args: Vec<String>,
89 pub env: HashMap<String, String>,
90 pub cwd: Option<PathBuf>,
91}
92
93pub(crate) type DeferredEnvironmentReadiness = Shared<oneshot::Receiver<Result<(), String>>>;
94
95#[derive(Clone)]
96pub(crate) struct Deferred<T> {
97 pub readiness: DeferredEnvironmentReadiness,
98 pub transport: T,
99}
100
101#[derive(Clone)]
103pub(crate) enum ExecServerTransportParams {
104 Deferred(Box<Deferred<ExecServerTransportParams>>),
105 WebSocketUrl {
106 websocket_url: String,
107 connect_timeout: Duration,
108 initialize_timeout: Duration,
109 },
110 NoiseRendezvous {
111 provider: Arc<dyn NoiseRendezvousConnectProvider>,
112 identity: NoiseChannelIdentity,
113 },
114 #[allow(dead_code)]
115 StdioCommand {
116 command: StdioExecServerCommand,
117 initialize_timeout: Duration,
118 },
119}
120
121impl std::fmt::Debug for ExecServerTransportParams {
122 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
123 match self {
124 Self::Deferred(deferred) => f
125 .debug_struct("Deferred")
126 .field("transport", &deferred.transport)
127 .finish_non_exhaustive(),
128 Self::WebSocketUrl {
129 websocket_url,
130 connect_timeout,
131 initialize_timeout,
132 } => f
133 .debug_struct("WebSocketUrl")
134 .field("websocket_url", websocket_url)
135 .field("connect_timeout", connect_timeout)
136 .field("initialize_timeout", initialize_timeout)
137 .finish(),
138 Self::NoiseRendezvous { .. } => {
139 f.debug_struct("NoiseRendezvous").finish_non_exhaustive()
140 }
141 Self::StdioCommand {
142 command,
143 initialize_timeout,
144 } => f
145 .debug_struct("StdioCommand")
146 .field("command", command)
147 .field("initialize_timeout", initialize_timeout)
148 .finish(),
149 }
150 }
151}
152
153impl ExecServerTransportParams {
154 pub(crate) fn websocket_url(websocket_url: String, connect_timeout: Duration) -> Self {
155 Self::WebSocketUrl {
156 websocket_url,
157 connect_timeout,
158 initialize_timeout: DEFAULT_REMOTE_EXEC_SERVER_INITIALIZE_TIMEOUT,
159 }
160 }
161}
162
163pub trait HttpClient: Send + Sync {
169 fn http_request(
171 &self,
172 params: HttpRequestParams,
173 ) -> BoxFuture<'_, Result<HttpRequestResponse, ExecServerError>>;
174
175 fn http_request_stream(
177 &self,
178 params: HttpRequestParams,
179 ) -> BoxFuture<'_, Result<(HttpRequestResponse, HttpResponseBodyStream), ExecServerError>>;
180}