Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/base/src/worker/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ impl WorkerPool {
() = &mut wait_timeout => {
if
tx
.send(Err(anyhow!("worker did not respond in time")))
.send(Err(anyhow!(WorkerError::WorkerCreationTimeout)))
.is_err()
{
error!("main worker receiver dropped");
Expand Down
6 changes: 3 additions & 3 deletions crates/base/tests/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1003,8 +1003,8 @@ async fn req_failure_case_timeout() {
if !found_timeout {
let buf = to_bytes(res.body_mut()).await.unwrap();
let status_500 = res.status() == StatusCode::INTERNAL_SERVER_ERROR;
let valid_output =
buf == "{\"msg\":\"InvalidWorkerCreation: worker did not respond in time\"}";
let valid_output = buf
== "{\"msg\":\"WorkerUnavailable: worker did not respond in time\"}";

found_timeout = status_500 && valid_output;
}
Expand Down Expand Up @@ -1181,7 +1181,7 @@ async fn req_failure_case_wall_clock_reached_less_than_100ms() {

assert!(
buf == "{\"msg\":\"InvalidWorkerResponse: user worker failed to respond\"}"
|| buf == "{\"msg\":\"InvalidWorkerCreation: worker did not respond in time\"}"
|| buf == "{\"msg\":\"WorkerUnavailable: worker did not respond in time\"}"
|| buf
== "{\"msg\":\"WorkerRequestCancelled: request has been cancelled by supervisor\"}"
);
Expand Down
3 changes: 3 additions & 0 deletions ext/workers/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,7 @@ pub enum WorkerError {
WorkerAlreadyRetired,
#[error("request timed out")]
RequestIdleTimeout,
/// The worker did not come up before the pool gave up waiting for it.
#[error("worker did not respond in time")]
WorkerCreationTimeout,
}
21 changes: 17 additions & 4 deletions ext/workers/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,17 +302,24 @@ pub async fn op_user_worker_create(
};

match result_rx.await {
// The pool dropped the sender, so no worker was produced and the module was
// never evaluated. Reported separately from a module that failed to
// evaluate, because only the latter is the caller's own code failing.
Err(err) => Err(custom_error(
"InvalidWorkerCreation",
"WorkerUnavailable",
format!(
"{:#}",
AnyError::from(err).context("failed to create worker")
),
)),

Ok(Err(err)) => {
Err(custom_error("InvalidWorkerCreation", format!("{err:#}")))
}
Ok(Err(err)) => Err(match err.downcast_ref::<WorkerError>() {
Some(WorkerError::WorkerCreationTimeout) => {
custom_error("WorkerUnavailable", format!("{err:#}"))
}
// Anything else reaching here came out of evaluating the module.
_ => custom_error("InvalidWorkerCreation", format!("{err:#}")),
}),
Ok(Ok(v)) => Ok((v.key.to_string(), v.reused)),
}
}
Expand Down Expand Up @@ -646,6 +653,12 @@ pub async fn op_user_worker_fetch_send(
err.to_string(),
));
}
// Raised while creating a worker, so it cannot reach a request that
// already has one. Listed rather than folded into a wildcard so a new
// variant still has to be decided here.
Some(err @ WorkerError::WorkerCreationTimeout) => {
return Err(custom_error("InvalidWorkerResponse", err.to_string()));
}

None => {
return Err(custom_error("InvalidWorkerResponse", err.to_string()));
Expand Down
Loading