* Add new component `ExecutionDuration` Reusable component helps with tracking execution time of job It is not using job.started_at, but instead uses it's own tracking mechanism The key difference that it can give insights during execution of job and measures pure execution time Accuracy is configurable with `updateResolution` Can also detect if job is `longRunning` e.g. runs more than X-seconds * Implement Hint for Explicit Progress It uses ExecutionDuration component introduced in previous commit and device's local storage to handle `Dont show again` * Remove dublication of `FlowProgressBar` in `run` page * Change Hint styling * Change values in `ExecutionDuration` to match required `longDefinition`: 3 -> 30 `updateResolution`: 2 -> 10 Meaning jobs running more than 30s counts as a `Long Running Job` * Fix broken link * Scope to langs: `python3`, `bun` and `deno` jobKinds: `script` * Simplify ExecutionDuration for new scope * Bring `preview` job kind into the scope We need this to show this tip in preview pages. e.g. By clicking on subjob details of flow (this subjob is preview)
99 lines
2.5 KiB
Svelte
99 lines
2.5 KiB
Svelte
<script lang="ts">
|
|
import { type Job } from '$lib/gen'
|
|
import ProgressBar from '../progressBar/ProgressBar.svelte'
|
|
|
|
export let job: Job | undefined = undefined
|
|
export let currentSubJobProgress: number | undefined = undefined
|
|
|
|
let error: number | undefined = undefined
|
|
let index = 0
|
|
let subIndex: number | undefined = undefined
|
|
let subLength: number | undefined = undefined
|
|
let length = 1
|
|
let nextInProgress = false
|
|
let subIndexIsPercent: boolean = false
|
|
|
|
$: if (job) updateJobProgress(job)
|
|
|
|
function updateJobProgress(job: Job) {
|
|
const modules = job?.flow_status?.modules
|
|
if (!modules?.length) {
|
|
return
|
|
}
|
|
|
|
let subStepIndex: undefined | number = undefined
|
|
let subStepLength: undefined | number = undefined
|
|
let newError: number | undefined = undefined
|
|
let newNextInProgress = false
|
|
|
|
let maxDone = Math.max(job?.flow_status?.step ?? 0, 0)
|
|
if (modules.length > maxDone) {
|
|
const nextModule = modules[maxDone]
|
|
if (nextModule.type === 'InProgress') {
|
|
newNextInProgress = true
|
|
}
|
|
}
|
|
|
|
let module = modules[maxDone]
|
|
if (module) {
|
|
if (module.type === 'Failure' || (module.type === 'Success' && job['success'] === false)) {
|
|
newError = maxDone
|
|
maxDone = maxDone + 1
|
|
}
|
|
}
|
|
subIndexIsPercent = false;
|
|
|
|
// Loop is still iterating
|
|
if (module?.iterator) {
|
|
const stepIndex = module.iterator.index || 0
|
|
const stepLength = module.iterator.itered?.length || 0
|
|
if (module.iterator.index != undefined) {
|
|
subStepIndex = stepIndex
|
|
subStepLength = stepLength
|
|
}
|
|
} else if (module?.branchall) {
|
|
subStepIndex = module.branchall.branch
|
|
subStepLength = module.branchall.len
|
|
} else if (module?.progress) {
|
|
const clamp = (num, min, max) => Math.min(Math.max(num, min), max)
|
|
subStepIndex = clamp(module?.progress, subIndex ?? 0, 99)
|
|
// Jitter protection >^^^^^^^^
|
|
subStepLength = 100
|
|
subIndexIsPercent = true;
|
|
currentSubJobProgress = subStepIndex
|
|
} else {
|
|
currentSubJobProgress = undefined
|
|
}
|
|
|
|
error = newError
|
|
subLength = subStepLength ? Math.max(subStepLength, 1) : undefined
|
|
subIndex = subStepIndex
|
|
length = Math.max(modules.length, 1)
|
|
index = maxDone
|
|
nextInProgress = newNextInProgress
|
|
}
|
|
|
|
let resetP: any
|
|
|
|
export function reset() {
|
|
resetP?.()
|
|
error = undefined
|
|
subIndex = undefined
|
|
subLength = undefined
|
|
length = 1
|
|
index = 0
|
|
}
|
|
</script>
|
|
|
|
<ProgressBar
|
|
bind:resetP
|
|
{length}
|
|
{index}
|
|
{nextInProgress}
|
|
{subLength}
|
|
{subIndex}
|
|
{error}
|
|
bind:subIndexIsPercent
|
|
class={$$props.class}
|
|
/>
|