@@ -229,6 +229,7 @@ export class PerformRunExecutionV3Service {
229
229
} ) ;
230
230
}
231
231
232
+ const taskCount = await getTaskCountForRun ( this . #prismaClient, run . id ) ;
232
233
const tasks = await getCompletedTasksForRun ( this . #prismaClient, run . id ) ;
233
234
234
235
const sourceContext = RunSourceContextSchema . safeParse ( run . event . sourceContext ) ;
@@ -428,7 +429,8 @@ export class PerformRunExecutionV3Service {
428
429
this . #prismaClient,
429
430
run ,
430
431
input ,
431
- durationInMs
432
+ durationInMs ,
433
+ taskCount
432
434
) ;
433
435
} else {
434
436
return await this . #failRunExecutionWithRetry(
@@ -1075,7 +1077,8 @@ export class PerformRunExecutionV3Service {
1075
1077
prisma : PrismaClientOrTransaction ,
1076
1078
run : FoundRun ,
1077
1079
input : PerformRunExecutionV3Input ,
1078
- durationInMs : number
1080
+ durationInMs : number ,
1081
+ existingTaskCount : number
1079
1082
) {
1080
1083
await $transaction ( prisma , async ( tx ) => {
1081
1084
const executionDuration = run . executionDuration + durationInMs ;
@@ -1096,6 +1099,47 @@ export class PerformRunExecutionV3Service {
1096
1099
return ;
1097
1100
}
1098
1101
1102
+ const newTaskCount = await getTaskCountForRun ( tx , run . id ) ;
1103
+
1104
+ if ( newTaskCount === existingTaskCount ) {
1105
+ const latestTask = await tx . task . findFirst ( {
1106
+ select : {
1107
+ id : true ,
1108
+ name : true ,
1109
+ status : true ,
1110
+ displayKey : true ,
1111
+ } ,
1112
+ where : {
1113
+ runId : run . id ,
1114
+ status : "RUNNING" ,
1115
+ } ,
1116
+ orderBy : {
1117
+ createdAt : "desc" ,
1118
+ } ,
1119
+ take : 1 ,
1120
+ } ) ;
1121
+
1122
+ const cause =
1123
+ latestTask ?. status === "RUNNING"
1124
+ ? `This is likely caused by task "${
1125
+ latestTask . displayKey ?? latestTask . name
1126
+ } " execution exceeding the function timeout`
1127
+ : "This is likely caused by executing code outside of a task that exceeded the function timeout" ;
1128
+
1129
+ await this . #failRunExecution(
1130
+ tx ,
1131
+ run ,
1132
+ {
1133
+ message : `Function timeout detected in ${
1134
+ durationInMs / 1000.0
1135
+ } s without any task creation. This is unexpected behavior and could lead to an infinite execution error because the run will never finish. ${ cause } `,
1136
+ } ,
1137
+ "TIMED_OUT" ,
1138
+ durationInMs
1139
+ ) ;
1140
+ return ;
1141
+ }
1142
+
1099
1143
await tx . jobRun . update ( {
1100
1144
where : {
1101
1145
id : run . id ,
@@ -1217,6 +1261,14 @@ function prepareNoOpTasksBloomFilter(possibleTasks: FoundTask[]): string {
1217
1261
return filter . serialize ( ) ;
1218
1262
}
1219
1263
1264
+ async function getTaskCountForRun ( prisma : PrismaClientOrTransaction , runId : string ) {
1265
+ return await prisma . task . count ( {
1266
+ where : {
1267
+ runId,
1268
+ } ,
1269
+ } ) ;
1270
+ }
1271
+
1220
1272
async function getCompletedTasksForRun ( prisma : PrismaClientOrTransaction , runId : string ) {
1221
1273
return await prisma . task . findMany ( {
1222
1274
where : {
0 commit comments