Skip to content

Commit 28dc711

Browse files
committed
chore: further optimisations
1 parent f6d0f7e commit 28dc711

File tree

6 files changed

+62
-31
lines changed

6 files changed

+62
-31
lines changed

crates/urt-executor/src/config.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,7 @@ pub struct ExecutorConfig {
319319
pub inactive_threshold: u64, // seconds
320320
pub maintenance_interval: u64, // seconds
321321
pub autoscale: bool,
322+
pub eager_runtime_readiness: bool,
322323
pub max_concurrent_executions: Option<usize>,
323324
pub max_concurrent_runtime_creates: Option<usize>,
324325
pub execution_queue_wait_ms: u64,
@@ -420,6 +421,9 @@ impl ExecutorConfig {
420421
autoscale: env_urt_or_opr("AUTOSCALE")
421422
.map(|v| parse_bool_flag(&v))
422423
.unwrap_or(false),
424+
eager_runtime_readiness: env_urt_or_opr("EAGER_RUNTIME_READINESS")
425+
.map(|v| parse_bool_flag(&v))
426+
.unwrap_or(false),
423427
max_concurrent_executions: env_urt_or_opr("MAX_CONCURRENT_EXECUTIONS")
424428
.and_then(|v| v.parse::<usize>().ok())
425429
.filter(|v| *v > 0),

crates/urt-executor/src/main.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ async fn async_main() -> Result<(), Box<dyn std::error::Error>> {
8181
info!(" Host: {}:{}", config.host, config.port);
8282
info!(" Keep-alive: {}", config.keep_alive);
8383
info!(" Autoscale: {}", config.autoscale);
84+
info!(
85+
" Eager runtime readiness: {}",
86+
config.eager_runtime_readiness
87+
);
8488
info!(" Metrics endpoint: {}", config.metrics_enabled);
8589
info!(" Auto runtime: {}", config.auto_runtime);
8690
info!(" Min CPUs: {}", config.min_cpus);

crates/urt-executor/src/routes/runtimes.rs

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,9 @@ pub async fn create_runtime(
502502
validate_image_name(&resolved_image)?;
503503

504504
let full_name = format!("{}-{}", state.config.hostname, req.runtime_id);
505-
reconcile_existing_runtime_id(&state, &req.runtime_id, &full_name).await?;
505+
if state.registry.exists(&full_name).await {
506+
reconcile_existing_runtime_id(&state, &req.runtime_id, &full_name).await?;
507+
}
506508

507509
// Check if image is allowed
508510
if !state.config.is_runtime_allowed(&resolved_image) {
@@ -1051,25 +1053,27 @@ pub async fn create_runtime(
10511053

10521054
info!("Cleaned up runtime {} after build", req.runtime_id);
10531055
} else {
1054-
let port_timeout_secs = u64::from(req.timeout.clamp(1, 30));
1055-
if let Err(error) =
1056-
wait_for_runtime_port(&full_name, 3000, Duration::from_secs(port_timeout_secs)).await
1057-
{
1058-
error!(
1059-
"Runtime {} failed port readiness: {}",
1060-
req.runtime_id, error
1061-
);
1062-
state.docker.remove_container(&full_name, true).await.ok();
1063-
tokio::fs::remove_dir_all(&tmp_folder).await.ok();
1064-
state.registry.remove(&full_name).await;
1065-
return Err(ExecutorError::RuntimeFailed(
1066-
"Runtime port readiness check timed out".to_string(),
1067-
));
1068-
}
1069-
10701056
let mut updated_runtime = runtime.clone();
1057+
if state.config.eager_runtime_readiness {
1058+
let port_timeout_secs = u64::from(req.timeout.clamp(1, 30));
1059+
if let Err(error) =
1060+
wait_for_runtime_port(&full_name, 3000, Duration::from_secs(port_timeout_secs))
1061+
.await
1062+
{
1063+
error!(
1064+
"Runtime {} failed port readiness: {}",
1065+
req.runtime_id, error
1066+
);
1067+
state.docker.remove_container(&full_name, true).await.ok();
1068+
tokio::fs::remove_dir_all(&tmp_folder).await.ok();
1069+
state.registry.remove(&full_name).await;
1070+
return Err(ExecutorError::RuntimeFailed(
1071+
"Runtime port readiness check timed out".to_string(),
1072+
));
1073+
}
1074+
updated_runtime.set_listening();
1075+
}
10711076
updated_runtime.mark_running("running");
1072-
updated_runtime.set_listening();
10731077
state.registry.update(updated_runtime).await.ok();
10741078
}
10751079

crates/urt-executor/src/runtime/protocol.rs

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,34 @@ use smallvec::SmallVec;
1212
use std::collections::HashMap;
1313
use std::fmt::Write;
1414
use std::path::Path;
15+
#[cfg(not(test))]
16+
use std::sync::OnceLock;
1517
use std::time::Duration;
1618
use tracing::debug;
1719

1820
/// Maximum log file size (5MB, matching executor-main)
1921
const MAX_LOG_SIZE: usize = 5 * 1024 * 1024;
2022
const MAX_BUILD_LOG_SIZE: usize = 1_000_000;
21-
const LOG_FILE_WAIT_TIMEOUT: Duration = Duration::from_secs(1);
2223
const LOG_FILE_WAIT_INTERVAL: Duration = Duration::from_millis(25);
2324

25+
#[cfg(not(test))]
26+
fn log_file_wait_timeout() -> Duration {
27+
static TIMEOUT: OnceLock<Duration> = OnceLock::new();
28+
*TIMEOUT.get_or_init(|| {
29+
let millis = std::env::var("URT_LOG_FILE_WAIT_MS")
30+
.ok()
31+
.or_else(|| std::env::var("OPR_EXECUTOR_LOG_FILE_WAIT_MS").ok())
32+
.and_then(|value| value.parse::<u64>().ok())
33+
.unwrap_or(0);
34+
Duration::from_millis(millis)
35+
})
36+
}
37+
38+
#[cfg(test)]
39+
fn log_file_wait_timeout() -> Duration {
40+
Duration::from_secs(1)
41+
}
42+
2443
/// Request to execute a function
2544
#[derive(Debug, Clone)]
2645
pub struct ExecuteRequest {
@@ -308,11 +327,7 @@ impl RuntimeProtocol for V5Protocol {
308327
}
309328

310329
pub fn runtime_network_host(runtime: &Runtime) -> &str {
311-
if runtime.hostname.trim().is_empty() {
312-
&runtime.name
313-
} else {
314-
&runtime.hostname
315-
}
330+
&runtime.name
316331
}
317332

318333
/// Read log files from disk and clean up (matching executor-main behavior)
@@ -345,7 +360,12 @@ async fn read_log_files(runtime_name: &str, file_id: &str) -> (String, String) {
345360
}
346361

347362
async fn wait_for_log_file(path: &Path) {
348-
let deadline = tokio::time::Instant::now() + LOG_FILE_WAIT_TIMEOUT;
363+
let timeout = log_file_wait_timeout();
364+
if timeout.is_zero() {
365+
return;
366+
}
367+
368+
let deadline = tokio::time::Instant::now() + timeout;
349369

350370
loop {
351371
if tokio::fs::try_exists(path).await.unwrap_or(false)
@@ -493,7 +513,7 @@ mod tests {
493513
}
494514

495515
#[test]
496-
fn test_runtime_network_host_prefers_hostname() {
516+
fn test_runtime_network_host_uses_container_name_even_when_hostname_exists() {
497517
let runtime = Runtime {
498518
version: "v5".to_string(),
499519
created: 0.0,
@@ -509,12 +529,9 @@ mod tests {
509529
authorization_header: "Basic dummy".to_string(),
510530
};
511531

512-
assert_eq!(
513-
runtime_network_host(&runtime),
514-
"1ca14d56857971dfad412b32f66e6466"
515-
);
532+
assert_eq!(runtime_network_host(&runtime), "exc1-myruntime123");
516533
let url = build_runtime_url(runtime_network_host(&runtime), 3000, "/");
517-
assert_eq!(url, "http://1ca14d56857971dfad412b32f66e6466:3000/");
534+
assert_eq!(url, "http://exc1-myruntime123:3000/");
518535
}
519536

520537
#[test]

crates/urt-executor/tests/e2e.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ fn test_config(network: String) -> ExecutorConfig {
119119
inactive_threshold: 300,
120120
maintenance_interval: 3600,
121121
autoscale: false,
122+
eager_runtime_readiness: false,
122123
max_concurrent_executions: None,
123124
max_concurrent_runtime_creates: None,
124125
execution_queue_wait_ms: 2_000,

crates/urt-executor/tests/integration.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ fn test_config() -> ExecutorConfig {
4040
inactive_threshold: 60,
4141
maintenance_interval: 3600,
4242
autoscale: false,
43+
eager_runtime_readiness: false,
4344
max_concurrent_executions: None,
4445
max_concurrent_runtime_creates: None,
4546
execution_queue_wait_ms: 2_000,

0 commit comments

Comments
 (0)