1use std::collections::HashMap;
2use std::net::SocketAddr;
3use std::sync::Arc;
4
5use anyhow::Result;
6use async_trait::async_trait;
7use hydro_deploy_integration::ServerBindConfig;
8use rust_crate::build::BuildOutput;
9use rust_crate::tracing_options::TracingOptions;
10use tokio::sync::{mpsc, oneshot};
11
12pub mod deployment;
13pub use deployment::Deployment;
14
15pub mod progress;
16
17pub mod localhost;
18pub use localhost::LocalhostHost;
19
20pub mod ssh;
21
22pub mod gcp;
23pub use gcp::GcpComputeEngineHost;
24
25pub mod azure;
26pub use azure::AzureHost;
27
28pub mod rust_crate;
29pub use rust_crate::RustCrate;
30
31pub mod custom_service;
32pub use custom_service::CustomService;
33
34pub mod terraform;
35
36pub mod util;
37
38#[derive(Default)]
39pub struct ResourcePool {
40 pub terraform: terraform::TerraformPool,
41}
42
43pub struct ResourceBatch {
44 pub terraform: terraform::TerraformBatch,
45}
46
47impl ResourceBatch {
48 fn new() -> ResourceBatch {
49 ResourceBatch {
50 terraform: terraform::TerraformBatch::default(),
51 }
52 }
53
54 async fn provision(
55 self,
56 pool: &mut ResourcePool,
57 last_result: Option<Arc<ResourceResult>>,
58 ) -> Result<ResourceResult> {
59 Ok(ResourceResult {
60 terraform: self.terraform.provision(&mut pool.terraform).await?,
61 _last_result: last_result,
62 })
63 }
64}
65
66#[derive(Debug)]
67pub struct ResourceResult {
68 pub terraform: terraform::TerraformResult,
69 _last_result: Option<Arc<ResourceResult>>,
70}
71
72#[derive(Clone)]
73pub struct TracingResults {
74 pub folded_data: Vec<u8>,
75}
76
77#[async_trait]
78pub trait LaunchedBinary: Send + Sync {
79 fn stdin(&self) -> mpsc::UnboundedSender<String>;
80
81 fn deploy_stdout(&self) -> oneshot::Receiver<String>;
86
87 fn stdout(&self) -> mpsc::UnboundedReceiver<String>;
88 fn stderr(&self) -> mpsc::UnboundedReceiver<String>;
89 fn stdout_filter(&self, prefix: String) -> mpsc::UnboundedReceiver<String>;
90 fn stderr_filter(&self, prefix: String) -> mpsc::UnboundedReceiver<String>;
91
92 fn tracing_results(&self) -> Option<&TracingResults>;
93
94 fn exit_code(&self) -> Option<i32>;
95
96 async fn wait(&mut self) -> Result<i32>;
98 async fn stop(&mut self) -> Result<()>;
100}
101
102#[async_trait]
103pub trait LaunchedHost: Send + Sync {
104 fn server_config(&self, strategy: &ServerStrategy) -> ServerBindConfig;
107
108 async fn copy_binary(&self, binary: &BuildOutput) -> Result<()>;
109
110 async fn launch_binary(
111 &self,
112 id: String,
113 binary: &BuildOutput,
114 args: &[String],
115 perf: Option<TracingOptions>,
116 ) -> Result<Box<dyn LaunchedBinary>>;
117
118 async fn forward_port(&self, addr: &SocketAddr) -> Result<SocketAddr>;
119}
120
121pub enum ServerStrategy {
123 UnixSocket,
124 InternalTcpPort,
125 ExternalTcpPort(
126 u16,
128 ),
129 Demux(HashMap<u32, ServerStrategy>),
130 Merge(Vec<ServerStrategy>),
131 Tagged(Box<ServerStrategy>, u32),
132 Null,
133}
134
135pub enum ClientStrategy<'a> {
137 UnixSocket(
138 usize,
140 ),
141 InternalTcpPort(
142 &'a dyn Host,
144 ),
145 ForwardedTcpPort(
146 &'a dyn Host,
148 ),
149}
150
151#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
152pub enum HostTargetType {
153 Local,
154 Linux,
155}
156
157pub type HostStrategyGetter = Box<dyn FnOnce(&dyn std::any::Any) -> ServerStrategy>;
158
159pub trait Host: Send + Sync {
160 fn target_type(&self) -> HostTargetType;
161
162 fn request_port(&self, bind_type: &ServerStrategy);
163
164 fn id(&self) -> usize;
166
167 fn request_custom_binary(&self);
169
170 fn collect_resources(&self, resource_batch: &mut ResourceBatch);
174
175 fn provision(&self, resource_result: &Arc<ResourceResult>) -> Arc<dyn LaunchedHost>;
179
180 fn launched(&self) -> Option<Arc<dyn LaunchedHost>>;
181
182 fn strategy_as_server<'a>(
185 &'a self,
186 connection_from: &dyn Host,
187 ) -> Result<(ClientStrategy<'a>, HostStrategyGetter)>;
188
189 fn can_connect_to(&self, typ: ClientStrategy) -> bool;
191
192 fn as_any(&self) -> &dyn std::any::Any;
194}
195
196#[async_trait]
197pub trait Service: Send + Sync {
198 fn collect_resources(&self, resource_batch: &mut ResourceBatch);
205
206 async fn deploy(&mut self, resource_result: &Arc<ResourceResult>) -> Result<()>;
208
209 async fn ready(&mut self) -> Result<()>;
212
213 async fn start(&mut self) -> Result<()>;
215
216 async fn stop(&mut self) -> Result<()>;
218}
219
220pub trait ServiceBuilder {
221 type Service: Service + 'static;
222 fn build(self, id: usize) -> Self::Service;
223}
224
225impl<S: Service + 'static, T: FnOnce(usize) -> S> ServiceBuilder for T {
226 type Service = S;
227 fn build(self, id: usize) -> Self::Service {
228 self(id)
229 }
230}