summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsoryu <soryu@soryu.co>2026-01-23 19:49:58 +0000
committerGitHub <noreply@github.com>2026-01-23 19:49:58 +0000
commitf6f0790217d4098ffb6d2b3df08b0cf83ff61727 (patch)
tree234287f703364a314b0fa2438a29750e27e67c81
parent5595a2fce2e426fd9f1b6224df467a2300f06238 (diff)
downloadsoryu-f6f0790217d4098ffb6d2b3df08b0cf83ff61727.tar.gz
soryu-f6f0790217d4098ffb6d2b3df08b0cf83ff61727.zip
feat: Add client-side polling for CLI wait command (#23)
* [WIP] Heartbeat checkpoint - 2026-01-23 03:34:44 UTC * feat: Add client-side polling for CLI wait command When contracts wait for tasks in makima, the CLI now polls and returns once the task has changed state. This provides resilient task status detection even if: - Server's broadcast channels miss a notification - Network connections are intermittent - Long-polling HTTP requests timeout at load balancers The implementation uses a hybrid approach: 1. First tries server-side wait with short timeout (30s) 2. Falls back to polling via supervisor_get_task endpoint 3. Configurable poll_interval (default 5s) via --poll-interval flag Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
-rw-r--r--makima/src/bin/makima.rs59
-rw-r--r--makima/src/daemon/cli/supervisor.rs6
2 files changed, 60 insertions, 5 deletions
diff --git a/makima/src/bin/makima.rs b/makima/src/bin/makima.rs
index f0db69c..1a307d1 100644
--- a/makima/src/bin/makima.rs
+++ b/makima/src/bin/makima.rs
@@ -335,11 +335,62 @@ async fn run_supervisor(
SupervisorCommand::Wait(args) => {
let client = ApiClient::new(args.common.api_url, args.common.api_key)?;
eprintln!(
- "Waiting for task {} (timeout: {}s)...",
- args.task_id, args.timeout
+ "Waiting for task {} (timeout: {}s, poll interval: {}s)...",
+ args.task_id, args.timeout, args.poll_interval
);
- let result = client.supervisor_wait(args.task_id, args.timeout).await?;
- println!("{}", serde_json::to_string(&result.0)?);
+
+ let start_time = std::time::Instant::now();
+ let timeout_duration = std::time::Duration::from_secs(args.timeout as u64);
+ let poll_interval = std::time::Duration::from_secs(args.poll_interval);
+ let server_wait_timeout = 30i32; // Short timeout for server-side wait
+
+ loop {
+ // Check if we've exceeded the total timeout
+ let remaining = timeout_duration.saturating_sub(start_time.elapsed());
+ if remaining.is_zero() {
+ eprintln!("Timeout reached after {}s", args.timeout);
+ let result = client.supervisor_get_task(args.task_id).await?;
+ println!("{}", serde_json::to_string(&result.0)?);
+ break;
+ }
+
+ // Try server-side wait with short timeout
+ let wait_timeout = std::cmp::min(server_wait_timeout, remaining.as_secs() as i32);
+
+ match client.supervisor_wait(args.task_id, wait_timeout).await {
+ Ok(result) => {
+ if let Some(completed) = result.0.get("completed").and_then(|c| c.as_bool()) {
+ if completed {
+ println!("{}", serde_json::to_string(&result.0)?);
+ break;
+ }
+ }
+ // Not completed yet, continue loop
+ eprintln!("Task still running (elapsed: {:?})", start_time.elapsed());
+ }
+ Err(e) => {
+ eprintln!("Warning: Server wait failed: {}. Falling back to polling...", e);
+ // Fall back to simple status poll
+ if let Ok(result) = client.supervisor_get_task(args.task_id).await {
+ if let Some(status) = result.0.get("status").and_then(|s| s.as_str()) {
+ if status == "done" || status == "failed" || status == "merged" {
+ let wait_response = serde_json::json!({
+ "taskId": args.task_id,
+ "status": status,
+ "completed": true,
+ "outputSummary": result.0.get("progressSummary")
+ });
+ println!("{}", serde_json::to_string(&wait_response)?);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // Small delay before retrying
+ tokio::time::sleep(poll_interval).await;
+ }
}
SupervisorCommand::ReadFile(args) => {
let client = ApiClient::new(args.common.api_url, args.common.api_key)?;
diff --git a/makima/src/daemon/cli/supervisor.rs b/makima/src/daemon/cli/supervisor.rs
index 7e17135..3bc8525 100644
--- a/makima/src/daemon/cli/supervisor.rs
+++ b/makima/src/daemon/cli/supervisor.rs
@@ -60,9 +60,13 @@ pub struct WaitArgs {
#[arg(index = 1)]
pub task_id: Uuid,
- /// Timeout in seconds
+ /// Timeout in seconds (total wait time)
#[arg(index = 2, default_value = "300")]
pub timeout: i32,
+
+ /// Polling interval in seconds (how often to check task status via client-side polling)
+ #[arg(long, default_value = "5")]
+ pub poll_interval: u64,
}
/// Arguments for read-file command.