mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-09 08:03:50 +00:00
feat: perpetual scripts
This commit is contained in:
+23
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "SELECT restart_unless_cancelled FROM script WHERE hash = $1 AND workspace_id = $2",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "restart_unless_cancelled",
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8",
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "1d27895aa42ccbb542479b19baefd62790205b529ab0d8af36f18c470e8bb838"
|
||||
}
|
||||
+4
-3
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "INSERT INTO script (workspace_id, hash, path, parent_hashes, summary, description, content, created_by, schema, is_template, extra_perms, lock, language, kind, tag, draft_only, envs, concurrent_limit, concurrency_time_window_s, cache_ttl, dedicated_worker, ws_error_handler_muted, priority) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9::text::json, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23)",
|
||||
"query": "INSERT INTO script (workspace_id, hash, path, parent_hashes, summary, description, content, created_by, schema, is_template, extra_perms, lock, language, kind, tag, draft_only, envs, concurrent_limit, concurrency_time_window_s, cache_ttl, dedicated_worker, ws_error_handler_muted, priority, restart_unless_cancelled) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9::text::json, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24)",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
@@ -61,10 +61,11 @@
|
||||
"Int4",
|
||||
"Bool",
|
||||
"Bool",
|
||||
"Int2"
|
||||
"Int2",
|
||||
"Bool"
|
||||
]
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "52ad1773a9f5a1b6be1bb16af408f051f27d3f21b615c468b85aa75b64d943db"
|
||||
"hash": "cc916f88edb1ac791cdfb24c37691db9048e7d921a628a1ff5b71fead1de5e3a"
|
||||
}
|
||||
@@ -2,4 +2,4 @@
|
||||
ALTER TABLE script ADD COLUMN timeout INTEGER;
|
||||
ALTER TABLE flow ADD COLUMN timeout INTEGER;
|
||||
ALTER TABLE script ADD COLUMN delete_after_use BOOLEAN;
|
||||
ALTER TABLE script ADD COLUMN restart_unless_cancelled SMALLINT;
|
||||
ALTER TABLE script ADD COLUMN restart_unless_cancelled BOOLEAN;
|
||||
|
||||
@@ -465,8 +465,8 @@ async fn create_script(
|
||||
"INSERT INTO script (workspace_id, hash, path, parent_hashes, summary, description, \
|
||||
content, created_by, schema, is_template, extra_perms, lock, language, kind, tag, \
|
||||
draft_only, envs, concurrent_limit, concurrency_time_window_s, cache_ttl, \
|
||||
dedicated_worker, ws_error_handler_muted, priority) \
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9::text::json, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23)",
|
||||
dedicated_worker, ws_error_handler_muted, priority, restart_unless_cancelled) \
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9::text::json, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24)",
|
||||
&w_id,
|
||||
&hash.0,
|
||||
ns.path,
|
||||
@@ -490,6 +490,7 @@ async fn create_script(
|
||||
ns.dedicated_worker,
|
||||
ns.ws_error_handler_muted.unwrap_or(false),
|
||||
ns.priority,
|
||||
ns.restart_unless_cancelled
|
||||
)
|
||||
.execute(&mut tx)
|
||||
.await?;
|
||||
|
||||
@@ -559,6 +559,63 @@ pub async fn add_completed_job<
|
||||
}
|
||||
}
|
||||
|
||||
if !queued_job.is_flow_step && queued_job.job_kind == JobKind::Script && canceled_by.is_none() {
|
||||
if let Some(hash) = queued_job.script_hash {
|
||||
let p = sqlx::query_scalar!(
|
||||
"SELECT restart_unless_cancelled FROM script WHERE hash = $1 AND workspace_id = $2",
|
||||
hash.0,
|
||||
&queued_job.workspace_id
|
||||
)
|
||||
.fetch_optional(db)
|
||||
.await?
|
||||
.flatten()
|
||||
.unwrap_or(false);
|
||||
|
||||
if p {
|
||||
let tx = PushIsolationLevel::IsolatedRoot(db.clone(), rsmq);
|
||||
|
||||
let (_uuid, tx) = push(
|
||||
db,
|
||||
tx,
|
||||
&queued_job.workspace_id,
|
||||
JobPayload::ScriptHash {
|
||||
hash,
|
||||
path: queued_job.script_path().to_string(),
|
||||
concurrent_limit: queued_job.concurrent_limit,
|
||||
concurrency_time_window_s: queued_job.concurrency_time_window_s,
|
||||
cache_ttl: queued_job.cache_ttl,
|
||||
dedicated_worker: None,
|
||||
language: queued_job
|
||||
.language
|
||||
.clone()
|
||||
.unwrap_or_else(|| ScriptLang::Deno),
|
||||
priority: queued_job.priority,
|
||||
},
|
||||
queued_job.args.clone(),
|
||||
&queued_job.created_by,
|
||||
&queued_job.email,
|
||||
queued_job.permissioned_as.clone(),
|
||||
None,
|
||||
queued_job.schedule_path.clone(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
false,
|
||||
false,
|
||||
None,
|
||||
queued_job.visible_to_owner,
|
||||
Some(queued_job.tag.clone()),
|
||||
queued_job.timeout,
|
||||
None,
|
||||
queued_job.priority,
|
||||
)
|
||||
.await?;
|
||||
if let Err(e) = tx.commit().await {
|
||||
tracing::error!("Could not restart job {}: {}", queued_job.id, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// tracing::error!("4 {:?}", start.elapsed());
|
||||
|
||||
Ok(queued_job.id)
|
||||
|
||||
@@ -210,7 +210,8 @@
|
||||
concurrency_time_window_s: script.concurrency_time_window_s,
|
||||
cache_ttl: script.cache_ttl,
|
||||
ws_error_handler_muted: script.ws_error_handler_muted,
|
||||
priority: script.priority
|
||||
priority: script.priority,
|
||||
restart_unless_cancelled: script.restart_unless_cancelled
|
||||
}
|
||||
})
|
||||
savedScript = cloneDeep(script) as NewScriptWithDraft
|
||||
@@ -643,6 +644,24 @@
|
||||
{/if}
|
||||
</div>
|
||||
</Section>
|
||||
<Section label="Perpetual Script">
|
||||
<div class="flex gap-2 shrink flex-col">
|
||||
<Toggle
|
||||
size="sm"
|
||||
checked={Boolean(script.restart_unless_cancelled)}
|
||||
on:change={() => {
|
||||
if (script.restart_unless_cancelled) {
|
||||
script.restart_unless_cancelled = undefined
|
||||
} else {
|
||||
script.restart_unless_cancelled = true
|
||||
}
|
||||
}}
|
||||
options={{
|
||||
right: 'Restart upon ending unless cancelled'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Section>
|
||||
<Section label="Dedicated Workers" eeOnly>
|
||||
<Toggle
|
||||
disabled={!$enterpriseLicense ||
|
||||
@@ -682,7 +701,7 @@
|
||||
</svelte:fragment>
|
||||
</Section>
|
||||
{#if !isCloudHosted()}
|
||||
<Section label="High priority script">
|
||||
<Section label="High priority script" eeOnly>
|
||||
<Toggle
|
||||
disabled={!$enterpriseLicense || isCloudHosted()}
|
||||
size="sm"
|
||||
|
||||
@@ -64,7 +64,6 @@ const display: ComponentSet = {
|
||||
'displaycomponent',
|
||||
'jobidlogcomponent',
|
||||
'jobidflowstatuscomponent',
|
||||
'customcomponent',
|
||||
'statcomponent',
|
||||
'menucomponent'
|
||||
]
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
superadmin,
|
||||
usageStore,
|
||||
userStore,
|
||||
workspaceStore
|
||||
workspaceStore,
|
||||
type UserExt
|
||||
} from '$lib/stores'
|
||||
import CenteredModal from '$lib/components/CenteredModal.svelte'
|
||||
import { afterNavigate, beforeNavigate, goto } from '$app/navigation'
|
||||
@@ -168,6 +169,22 @@
|
||||
}
|
||||
|
||||
let devOnly = $page.url.pathname.startsWith('/scripts/dev')
|
||||
|
||||
$: onUserStore($userStore)
|
||||
|
||||
let timeout: NodeJS.Timeout | undefined
|
||||
async function onUserStore(u: UserExt | undefined) {
|
||||
if (u && timeout) {
|
||||
clearTimeout(timeout)
|
||||
timeout = undefined
|
||||
} else if (!u) {
|
||||
timeout = setTimeout(async () => {
|
||||
if (!$userStore && $workspaceStore) {
|
||||
$userStore = await getUserExt($workspaceStore)
|
||||
}
|
||||
}, 5000)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window bind:innerWidth />
|
||||
|
||||
Reference in New Issue
Block a user