feat(job): run job by hash (#551)

It was possible to run them using a webhook, but not through an endpoint.
This PR aims to fix that so the user can target a specific version of
the script to run.
This commit is contained in:
ex0ns
2022-09-11 16:39:48 +02:00
committed by GitHub
parent a65025a45b
commit dc55d45bae
2 changed files with 72 additions and 23 deletions

View File

@@ -50,6 +50,10 @@ pub fn workspaced_service() -> Router {
"/run_wait_result/p/*script_path",
post(run_wait_result_job_by_path),
)
.route(
"/run_wait_result/h/:hash",
post(run_wait_result_job_by_hash),
)
.route("/run/h/:hash", post(run_job_by_hash))
.route("/run/preview", post(run_preview_job))
.route("/run/preview_flow", post(run_preview_flow_job))
@@ -222,6 +226,38 @@ pub async fn run_job_by_path(
Ok((StatusCode::CREATED, uuid.to_string()))
}
async fn run_wait_result<T>(
authed: Authed,
Extension(user_db): Extension<UserDB>,
uuid: Uuid,
Path((w_id, _)): Path<(String, T)>,
) -> error::JsonResult<serde_json::Value> {
let mut result = None;
for i in 0..48 {
let mut tx = user_db.clone().begin(&authed).await?;
result = sqlx::query_scalar!(
"SELECT result FROM completed_job WHERE id = $1 AND workspace_id = $2",
uuid,
&w_id
)
.fetch_optional(&mut tx)
.await?
.flatten();
if result.is_some() {
break;
}
let delay = if i < 10 { 100 } else { 500 };
tokio::time::sleep(core::time::Duration::from_millis(delay)).await;
}
if let Some(result) = result {
Ok(Json(result))
} else {
Err(Error::ExecutionErr("timeout after 20s".to_string()))
}
}
pub async fn run_wait_result_job_by_path(
authed: Authed,
Extension(user_db): Extension<UserDB>,
@@ -249,31 +285,37 @@ pub async fn run_wait_result_job_by_path(
.await?;
tx.commit().await?;
//wait 5 secs top
let mut result = None;
for i in 0..48 {
let mut tx = user_db.clone().begin(&authed).await?;
run_wait_result(authed, Extension(user_db), uuid, Path((w_id, script_path))).await
}
result = sqlx::query_scalar!(
"SELECT result FROM completed_job WHERE id = $1 AND workspace_id = $2",
uuid,
&w_id
)
.fetch_optional(&mut tx)
.await?
.flatten();
pub async fn run_wait_result_job_by_hash(
authed: Authed,
Extension(user_db): Extension<UserDB>,
Path((w_id, script_hash)): Path<(String, ScriptHash)>,
axum::Json(args): axum::Json<Option<Map<String, Value>>>,
Query(run_query): Query<RunJobQuery>,
) -> error::JsonResult<serde_json::Value> {
let hash = script_hash.0;
let mut tx = user_db.clone().begin(&authed).await?;
let path = get_path_for_hash(&mut tx, &w_id, hash).await?;
let scheduled_for = run_query.get_scheduled_for(&mut tx).await?;
if result.is_some() {
break;
}
let delay = if i < 10 { 100 } else { 500 };
tokio::time::sleep(core::time::Duration::from_millis(delay)).await;
}
if let Some(result) = result {
Ok(Json(result))
} else {
Err(Error::ExecutionErr("timeout after 20s".to_string()))
}
let (uuid, tx) = push(
tx,
&w_id,
JobPayload::ScriptHash { hash: ScriptHash(hash), path },
args,
&authed.username,
owner_to_token_owner(&authed.username, false),
scheduled_for,
None,
run_query.parent_job,
false,
)
.await?;
tx.commit().await?;
run_wait_result(authed, Extension(user_db), uuid, Path((w_id, script_hash))).await
}
pub async fn script_path_to_payload<'c>(

View File

@@ -347,6 +347,13 @@
>{$page.url.hostname}/api/w/{$workspaceStore}/jobs/run_wait_result/p/{script?.path}</a
></code
></pre>
<pre><code
><a
href="//{$page.url
.hostname}/api/w/{$workspaceStore}/jobs/run_wait_result/h/{script?.hash}"
>{$page.url.hostname}/api/w/{$workspaceStore}/jobs/run_wait_result/h/{script?.hash}</a
></code
></pre>
</div>
<div>
<h3>