11import CronParser from "cron-parser" ; // Or your chosen cron library
2- import { and , eq , lte } from "drizzle-orm" ;
32import { drizzle } from "drizzle-orm/d1" ;
3+ import { Node , Workflow as WorkflowType } from "@dafthunk/types" ; // Using Workflow as WorkflowType from types
4+ import { ExecutionContext } from "@cloudflare/workers-types" ;
45
5- import { cronTriggers } from "./db/schema" ;
6+ import * as schema from "./db/schema" ;
7+ import { WorkflowRow } from "./db/schema" ;
8+ import { getDueCronTriggers , updateCronTriggerRunTimes , saveExecution } from "./db/queries" ;
9+ import { createDatabase , ExecutionStatusType } from "./db" ; // Added ExecutionStatusType
10+ import { Bindings } from "./context" ; // For the full env type
611
7- // This is a placeholder. You need to implement how workflows are triggered.
8- // If executeWorkflow becomes more complex or used elsewhere, it could also be in its own file.
12+ // This function will now handle the actual execution triggering and initial record saving
913async function executeWorkflow (
10- workflowId : string ,
11- _env : any ,
12- _ctx : any
14+ workflowRow : WorkflowRow ,
15+ db : ReturnType < typeof createDatabase > ,
16+ env : Bindings ,
17+ _ctx : ExecutionContext
1318) : Promise < void > {
14- console . log ( `Executing workflow ${ workflowId } ` ) ;
15- // Example: await fetch(`https://your-service.com/api/execute-workflow/${workflowId}`, { method: 'POST' });
16- // Or: directly call a function if workflow logic is bundled
17- // Remember to handle errors appropriately.
18- await Promise . resolve ( ) ; // Replace with actual workflow execution logic
19+ console . log ( `Attempting to execute workflow ${ workflowRow . id } via cron.` ) ;
20+
21+ // Assuming workflowRow.data is of type WorkflowType from @dafthunk /types
22+ // which includes type, nodes, and edges.
23+ const workflowData : WorkflowType = workflowRow . data ;
24+
25+ try {
26+ const executionInstance = await env . EXECUTE . create ( {
27+ params : {
28+ userId : "cron_trigger" ,
29+ organizationId : workflowRow . organizationId ,
30+ workflow : {
31+ id : workflowRow . id ,
32+ name : workflowRow . name ,
33+ handle : workflowRow . handle ,
34+ type : workflowData . type , // Reinstated: type from workflow data
35+ nodes : workflowData . nodes , // Reinstated: nodes from workflow data
36+ edges : workflowData . edges , // Reinstated: edges from workflow data
37+ } ,
38+ monitorProgress : false ,
39+ deploymentId : undefined ,
40+ } ,
41+ } ) ;
42+
43+ const executionId = executionInstance . id ;
44+ console . log ( `Workflow ${ workflowRow . id } started with execution ID: ${ executionId } ` ) ;
45+
46+ const nodeExecutions = workflowData . nodes . map ( ( node : Node ) => ( {
47+ nodeId : node . id ,
48+ status : "idle" as const ,
49+ } ) ) ;
50+
51+ await saveExecution ( db , {
52+ id : executionId ,
53+ workflowId : workflowRow . id ,
54+ deploymentId : undefined ,
55+ userId : "cron_trigger" ,
56+ organizationId : workflowRow . organizationId ,
57+ status : "executing" as ExecutionStatusType ,
58+ visibility : "private" ,
59+ nodeExecutions,
60+ createdAt : new Date ( ) ,
61+ updatedAt : new Date ( ) ,
62+ startedAt : new Date ( ) ,
63+ } ) ;
64+ console . log ( `Initial execution record saved for ${ executionId } ` ) ;
65+
66+ } catch ( execError ) {
67+ console . error ( `Error executing workflow ${ workflowRow . id } or saving initial record:` , execError ) ;
68+ }
1969}
2070
2171export async function handleCronTriggers (
2272 event : ScheduledEvent ,
23- env : { DB : D1Database } ,
73+ env : Bindings , // Updated to use the full Bindings type
2474 ctx : ExecutionContext
2575) : Promise < void > {
2676 console . log ( `Cron event triggered at: ${ new Date ( event . scheduledTime ) } ` ) ;
27- const db = drizzle ( env . DB , { schema : { cronTriggers } } ) ;
77+ // Ensure db is initialized correctly if createDatabase is the standard way
78+ // drizzle can also be initialized with just env.DB and schema
79+ const db = createDatabase ( env . DB ) ;
2880
2981 const now = new Date ( ) ;
3082
3183 try {
32- const dueTriggers = await db
33- . select ( )
34- . from ( cronTriggers )
35- . where (
36- and ( eq ( cronTriggers . active , true ) , lte ( cronTriggers . nextRunAt , now ) )
37- )
38- . all ( ) ;
84+ const dueTriggers = await getDueCronTriggers ( db , now ) ;
3985
4086 if ( dueTriggers . length === 0 ) {
4187 console . log ( "No due cron triggers found." ) ;
@@ -44,34 +90,35 @@ export async function handleCronTriggers(
4490
4591 console . log ( `Found ${ dueTriggers . length } due cron triggers.` ) ;
4692
47- for ( const trigger of dueTriggers ) {
48- console . log ( `Processing trigger for workflow: ${ trigger . workflowId } ` ) ;
93+ for ( const item of dueTriggers ) {
94+ // item contains { cronTrigger: CronTriggerRow, workflow: WorkflowRow }
95+ console . log ( `Processing trigger for workflow: ${ item . workflow . id } ` ) ;
4996 try {
50- // 1. Execute the workflow
51- await executeWorkflow ( trigger . workflowId , env , ctx ) ;
97+ // 1. Execute the workflow (asynchronously, no await here if we don't wait for termination)
98+ // However, executeWorkflow itself is async due to EXECUTE.create and saveExecution.
99+ // We should await it to ensure the initial saveExecution completes before updating run times.
100+ await executeWorkflow ( item . workflow , db , env , ctx ) ;
52101
53102 // 2. Calculate next run time
54- const interval = CronParser . parse ( trigger . cronExpression , {
103+ const interval = CronParser . parse ( item . cronTrigger . cronExpression , {
55104 currentDate : now ,
56105 } ) ;
57106 const nextRun = interval . next ( ) . toDate ( ) ;
58107
59108 // 3. Update the trigger in the database
60- await db
61- . update ( cronTriggers )
62- . set ( {
63- lastRun : now ,
64- nextRunAt : nextRun ,
65- } )
66- . where ( eq ( cronTriggers . workflowId , trigger . workflowId ) )
67- . execute ( ) ;
109+ await updateCronTriggerRunTimes (
110+ db ,
111+ item . cronTrigger . workflowId ,
112+ nextRun ,
113+ now
114+ ) ;
68115
69116 console . log (
70- `Workflow ${ trigger . workflowId } executed . Next run at: ${ nextRun . toISOString ( ) } `
117+ `Workflow ${ item . workflow . id } processing initiated . Next run at: ${ nextRun . toISOString ( ) } `
71118 ) ;
72119 } catch ( err ) {
73120 console . error (
74- `Error processing trigger for workflow ${ trigger . workflowId } :` ,
121+ `Error processing trigger for workflow ${ item . workflow . id } :` ,
75122 err
76123 ) ;
77124 // Optionally, you might want to implement retry logic or disable the trigger after too many failures.
0 commit comments