diff --git a/crates/worker-runtime/src/runtime.rs b/crates/worker-runtime/src/runtime.rs index 50e0acbb..ea3f28b4 100644 --- a/crates/worker-runtime/src/runtime.rs +++ b/crates/worker-runtime/src/runtime.rs @@ -1800,16 +1800,6 @@ impl Runtime { state.ensure_running()?; state.ensure_worker_ref(worker_ref)?; - { - let worker = state.worker(worker_ref)?; - if !worker.status.is_active() { - return Ok(WorkerLifecycleAck { - worker_ref: worker_ref.clone(), - status: worker.status, - }); - } - } - let worker = state.worker_mut(worker_ref)?; worker.status = status; worker.restore_intent = restore_intent_for_status(status); diff --git a/crates/worker-runtime/src/worker_backend.rs b/crates/worker-runtime/src/worker_backend.rs index e9141379..ef3da9bb 100644 --- a/crates/worker-runtime/src/worker_backend.rs +++ b/crates/worker-runtime/src/worker_backend.rs @@ -3665,6 +3665,60 @@ mod tests { assert_eq!(call_count.load(Ordering::SeqCst), 3); } + #[test] + fn stopped_runtime_worker_can_restore_and_accept_input() { + let client = MockClient::new(simple_text_events()); + let runtime_base = tempfile::tempdir().unwrap(); + let cwd = tempfile::tempdir().unwrap(); + let store = tempfile::tempdir().unwrap(); + let factory = MockFactory { + client, + runtime_base: runtime_base.path().to_path_buf(), + cwd: cwd.path().to_path_buf(), + store_dir: store.path().join("sessions"), + worker_metadata_dir: store.path().join("workers"), + observed_cwds: Arc::new(Mutex::new(Vec::new())), + observed_workspace_clients: Arc::new(Mutex::new(Vec::new())), + }; + let backend = Arc::new(WorkerRuntimeExecutionBackend::new(factory).unwrap()); + let runtime = + EmbeddedRuntime::with_execution_backend(RuntimeOptions::default(), backend.clone()) + .unwrap(); + runtime.store_config_bundle(test_bundle()).unwrap(); + let detail = runtime + .create_worker(create_request("restore-after-stop")) + .unwrap(); + + runtime.stop_worker(&detail.worker_ref, None).unwrap(); + assert_eq!( + runtime.worker_detail(&detail.worker_ref).unwrap().status, + crate::catalog::WorkerStatus::Stopped + ); + assert!( + !backend + .workers + .lock() + .unwrap() + .contains_key(&detail.worker_ref) + ); + + runtime.restore_worker(&detail.worker_ref).unwrap(); + assert_eq!( + runtime.worker_detail(&detail.worker_ref).unwrap().status, + crate::catalog::WorkerStatus::Idle + ); + assert!( + backend + .workers + .lock() + .unwrap() + .contains_key(&detail.worker_ref) + ); + runtime + .send_input(&detail.worker_ref, WorkerInput::user("continue")) + .unwrap(); + } + #[test] fn stopping_and_deleting_worker_preserves_bound_working_directory() { let client = MockClient::new(simple_text_events());