go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/projects/nodes/static/_nextjs/src/api/workflow.ts (about) 1 /** 2 * Copyright (c) 2024 - Present. Will Charczuk. All rights reserved. 3 * Use of this source code is governed by a MIT license that can be found in the LICENSE file at the root of the repository. 4 */ 5 export interface WorkflowRunInfo { 6 workflow_id: string; 7 run_id: string; 8 } 9 10 export interface WorkflowRunFailureCause { 11 message: string; 12 source: string; 13 } 14 15 export interface WorkflowRunFailure { 16 message: string; 17 source: string; 18 cause: WorkflowRunFailureCause 19 } 20 21 export interface WorkflowRunStatus { 22 workflow_id: string 23 run_id: string 24 task_queue: string 25 status: string 26 start_time: Date 27 close_time: Date 28 failure?: WorkflowRunFailure 29 } 30 31 export async function stabilize(graphId: string, parallel: boolean): Promise<WorkflowRunInfo> { 32 const res = await fetch(`/api/v1/graph/${graphId}/stabilize?${parallel ? 'parallel' : ''}`, { 33 method: "POST", 34 }); 35 if (!res?.ok) { 36 const message = (await res.json()) as string; 37 throw new Error(message) 38 } 39 const data = await res.json(); 40 return data as WorkflowRunInfo; 41 }; 42 43 export async function getRunStatus(workflowId: string, runId: string): Promise<WorkflowRunStatus> { 44 const res = await fetch(`/api/v1/workflow/${workflowId}/status/${runId}`, { 45 method: "GET", 46 }); 47 if (!res?.ok) { 48 const message = (await res.json()) as string; 49 throw new Error(message) 50 } 51 const data = await res.json(); 52 return data as WorkflowRunStatus; 53 } 54 55 const backoffs = [ 56 100, 100, 100, 100, 100, // 500ms 57 500, // 1000ms 58 1000, 1000, 1000, 1000, // 5000s 59 5000, 5000, 5000, 5000, 5000, // 30s 60 5000, 5000, 5000, 5000, 5000, 5000, // 60s 61 ] 62 63 export async function pollUntilFinished(workflowId: string, runId: string): Promise<WorkflowRunStatus> { 64 let status = await getRunStatus(workflowId, runId); 65 if (isFinished(status)) { 66 return status 67 } 68 69 for (let attempt = 0; attempt < backoffs.length; attempt++) { 70 await new Promise(f => setTimeout(f, backoffs[attempt])); 71 status = await getRunStatus(workflowId, runId); 72 if (isFinished(status)) { 73 return status 74 } 75 } 76 throw new Error("workflow execution timed out after 60 seconds"); 77 } 78 79 function isFinished(runStatus: WorkflowRunStatus): boolean { 80 return runStatus.status !== 'Unknown' && runStatus.status !== "Running" 81 }