2026-03-21 12:57:09 +08:00
|
|
|
use std::path::PathBuf;
|
|
|
|
|
|
|
|
|
|
use clap::Parser;
|
|
|
|
|
use tracing::info;
|
|
|
|
|
|
2026-04-03 14:59:58 +08:00
|
|
|
use aether_gateway::{serve_execution_runtime_tcp, serve_execution_runtime_unix};
|
2026-05-08 00:18:12 +08:00
|
|
|
use aether_runtime::{init_service_runtime, ServiceRuntimeConfig};
|
|
|
|
|
use aether_runtime_state::{RedisClientConfig, RuntimeSemaphoreConfig, RuntimeState};
|
2026-03-21 12:57:09 +08:00
|
|
|
|
|
|
|
|
#[derive(Parser, Debug)]
|
2026-04-03 14:59:58 +08:00
|
|
|
#[command(
|
|
|
|
|
name = "execution-runtime-harness",
|
|
|
|
|
about = "Internal execution runtime harness for Aether tests"
|
|
|
|
|
)]
|
2026-03-21 12:57:09 +08:00
|
|
|
struct Args {
|
2026-04-03 14:59:58 +08:00
|
|
|
#[arg(
|
|
|
|
|
long,
|
|
|
|
|
env = "AETHER_EXECUTION_RUNTIME_TRANSPORT",
|
|
|
|
|
default_value = "unix_socket"
|
|
|
|
|
)]
|
2026-03-21 12:57:09 +08:00
|
|
|
transport: String,
|
|
|
|
|
|
2026-04-03 14:59:58 +08:00
|
|
|
#[arg(
|
|
|
|
|
long,
|
|
|
|
|
env = "AETHER_EXECUTION_RUNTIME_BIND",
|
|
|
|
|
default_value = "127.0.0.1:5219"
|
|
|
|
|
)]
|
2026-03-21 12:57:09 +08:00
|
|
|
bind: String,
|
|
|
|
|
|
|
|
|
|
#[arg(
|
|
|
|
|
long,
|
2026-04-03 14:59:58 +08:00
|
|
|
env = "AETHER_EXECUTION_RUNTIME_UNIX_SOCKET",
|
|
|
|
|
default_value = "/tmp/aether-execution-runtime.sock"
|
2026-03-21 12:57:09 +08:00
|
|
|
)]
|
|
|
|
|
unix_socket: PathBuf,
|
2026-03-24 15:12:56 +08:00
|
|
|
|
2026-04-03 14:59:58 +08:00
|
|
|
#[arg(long, env = "AETHER_EXECUTION_RUNTIME_MAX_IN_FLIGHT_REQUESTS")]
|
2026-03-24 15:12:56 +08:00
|
|
|
max_in_flight_requests: Option<usize>,
|
|
|
|
|
|
2026-04-03 14:59:58 +08:00
|
|
|
#[arg(long, env = "AETHER_EXECUTION_RUNTIME_DISTRIBUTED_REQUEST_LIMIT")]
|
2026-03-24 15:12:56 +08:00
|
|
|
distributed_request_limit: Option<usize>,
|
|
|
|
|
|
2026-04-03 14:59:58 +08:00
|
|
|
#[arg(long, env = "AETHER_EXECUTION_RUNTIME_DISTRIBUTED_REQUEST_REDIS_URL")]
|
2026-03-24 15:12:56 +08:00
|
|
|
distributed_request_redis_url: Option<String>,
|
|
|
|
|
|
2026-04-03 14:59:58 +08:00
|
|
|
#[arg(
|
|
|
|
|
long,
|
|
|
|
|
env = "AETHER_EXECUTION_RUNTIME_DISTRIBUTED_REQUEST_REDIS_KEY_PREFIX"
|
|
|
|
|
)]
|
2026-03-24 15:12:56 +08:00
|
|
|
distributed_request_redis_key_prefix: Option<String>,
|
|
|
|
|
|
|
|
|
|
#[arg(
|
|
|
|
|
long,
|
2026-04-03 14:59:58 +08:00
|
|
|
env = "AETHER_EXECUTION_RUNTIME_DISTRIBUTED_REQUEST_LEASE_TTL_MS",
|
2026-03-24 15:12:56 +08:00
|
|
|
default_value_t = 30_000
|
|
|
|
|
)]
|
|
|
|
|
distributed_request_lease_ttl_ms: u64,
|
|
|
|
|
|
|
|
|
|
#[arg(
|
|
|
|
|
long,
|
2026-04-03 14:59:58 +08:00
|
|
|
env = "AETHER_EXECUTION_RUNTIME_DISTRIBUTED_REQUEST_RENEW_INTERVAL_MS",
|
2026-03-24 15:12:56 +08:00
|
|
|
default_value_t = 10_000
|
|
|
|
|
)]
|
|
|
|
|
distributed_request_renew_interval_ms: u64,
|
|
|
|
|
|
|
|
|
|
#[arg(
|
|
|
|
|
long,
|
2026-04-03 14:59:58 +08:00
|
|
|
env = "AETHER_EXECUTION_RUNTIME_DISTRIBUTED_REQUEST_COMMAND_TIMEOUT_MS",
|
2026-03-24 15:12:56 +08:00
|
|
|
default_value_t = 1_000
|
|
|
|
|
)]
|
|
|
|
|
distributed_request_command_timeout_ms: u64,
|
2026-03-21 12:57:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
|
|
|
let _ = rustls::crypto::ring::default_provider().install_default();
|
|
|
|
|
|
2026-03-24 15:12:56 +08:00
|
|
|
init_service_runtime(ServiceRuntimeConfig::new(
|
2026-04-03 14:59:58 +08:00
|
|
|
"aether-execution-runtime-harness",
|
|
|
|
|
"aether_gateway=info",
|
2026-03-24 15:12:56 +08:00
|
|
|
))?;
|
2026-03-21 12:57:09 +08:00
|
|
|
|
|
|
|
|
let args = Args::parse();
|
2026-03-24 15:12:56 +08:00
|
|
|
let distributed_request_gate = match args.distributed_request_limit.filter(|limit| *limit > 0) {
|
|
|
|
|
Some(limit) => {
|
|
|
|
|
let redis_url = args
|
|
|
|
|
.distributed_request_redis_url
|
|
|
|
|
.as_deref()
|
|
|
|
|
.map(str::trim)
|
|
|
|
|
.filter(|value| !value.is_empty())
|
|
|
|
|
.ok_or_else(|| {
|
2026-04-03 14:59:58 +08:00
|
|
|
std::io::Error::new(
|
|
|
|
|
std::io::ErrorKind::InvalidInput,
|
2026-05-08 00:18:12 +08:00
|
|
|
"AETHER_EXECUTION_RUNTIME_DISTRIBUTED_REQUEST_REDIS_URL is required when distributed request limit is enabled",
|
|
|
|
|
)
|
2026-03-24 15:12:56 +08:00
|
|
|
})?;
|
2026-05-08 00:18:12 +08:00
|
|
|
let runtime = RuntimeState::redis(
|
|
|
|
|
RedisClientConfig {
|
2026-03-24 15:12:56 +08:00
|
|
|
url: redis_url.to_string(),
|
|
|
|
|
key_prefix: args
|
|
|
|
|
.distributed_request_redis_key_prefix
|
|
|
|
|
.as_deref()
|
|
|
|
|
.map(str::trim)
|
|
|
|
|
.filter(|value| !value.is_empty())
|
|
|
|
|
.map(ToOwned::to_owned),
|
2026-05-08 00:18:12 +08:00
|
|
|
},
|
|
|
|
|
Some(args.distributed_request_command_timeout_ms.max(1)),
|
|
|
|
|
)
|
|
|
|
|
.await?;
|
|
|
|
|
Some(runtime.semaphore(
|
|
|
|
|
"execution_runtime_requests_distributed",
|
|
|
|
|
limit,
|
|
|
|
|
RuntimeSemaphoreConfig {
|
2026-03-24 15:12:56 +08:00
|
|
|
lease_ttl_ms: args.distributed_request_lease_ttl_ms.max(1),
|
|
|
|
|
renew_interval_ms: args.distributed_request_renew_interval_ms.max(1),
|
|
|
|
|
command_timeout_ms: Some(args.distributed_request_command_timeout_ms.max(1)),
|
|
|
|
|
},
|
|
|
|
|
)?)
|
|
|
|
|
}
|
|
|
|
|
None => None,
|
|
|
|
|
};
|
2026-04-03 14:59:58 +08:00
|
|
|
|
2026-03-21 12:57:09 +08:00
|
|
|
match args.transport.trim().to_ascii_lowercase().as_str() {
|
|
|
|
|
"unix_socket" | "unix" | "uds" => {
|
2026-04-03 14:59:58 +08:00
|
|
|
info!(
|
|
|
|
|
socket = %args.unix_socket.display(),
|
|
|
|
|
"aether execution-runtime harness started"
|
|
|
|
|
);
|
|
|
|
|
serve_execution_runtime_unix(
|
2026-03-24 15:12:56 +08:00
|
|
|
&args.unix_socket,
|
|
|
|
|
args.max_in_flight_requests,
|
|
|
|
|
distributed_request_gate.clone(),
|
|
|
|
|
)
|
|
|
|
|
.await?;
|
2026-03-21 12:57:09 +08:00
|
|
|
}
|
|
|
|
|
"tcp" => {
|
2026-03-24 15:12:56 +08:00
|
|
|
info!(
|
|
|
|
|
bind = %args.bind,
|
|
|
|
|
max_in_flight_requests = args.max_in_flight_requests.unwrap_or_default(),
|
|
|
|
|
distributed_request_limit = args.distributed_request_limit.unwrap_or_default(),
|
2026-04-03 14:59:58 +08:00
|
|
|
"aether execution-runtime harness started"
|
2026-03-24 15:12:56 +08:00
|
|
|
);
|
2026-04-03 14:59:58 +08:00
|
|
|
serve_execution_runtime_tcp(
|
2026-03-24 15:12:56 +08:00
|
|
|
&args.bind,
|
|
|
|
|
args.max_in_flight_requests,
|
|
|
|
|
distributed_request_gate,
|
|
|
|
|
)
|
|
|
|
|
.await?;
|
2026-03-21 12:57:09 +08:00
|
|
|
}
|
|
|
|
|
other => {
|
2026-04-03 14:59:58 +08:00
|
|
|
return Err(format!("unsupported execution runtime transport: {other}").into());
|
2026-03-21 12:57:09 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|