|
3 | 3 | packetRequiresOffloading, |
4 | 4 | QueueOptions, |
5 | 5 | SemanticInternalAttributes, |
| 6 | + taskRunErrorToString, |
| 7 | + taskRunErrorEnhancer, |
6 | 8 | TriggerTaskRequestBody, |
7 | 9 | } from "@trigger.dev/core/v3"; |
8 | 10 | import { |
@@ -39,6 +41,8 @@ import { |
39 | 41 | TriggerTaskServiceOptions, |
40 | 42 | TriggerTaskServiceResult, |
41 | 43 | } from "./triggerTask.server"; |
| 44 | +import { getTaskEventStore } from "../taskEventStore.server"; |
| 45 | +import { enqueueRun } from "./enqueueRun.server"; |
42 | 46 |
|
43 | 47 | /** @deprecated Use TriggerTaskService in `triggerTask.server.ts` instead. */ |
44 | 48 | export class TriggerTaskServiceV1 extends BaseService { |
@@ -168,6 +172,8 @@ export class TriggerTaskServiceV1 extends BaseService { |
168 | 172 | taskIdentifier: true, |
169 | 173 | rootTaskRunId: true, |
170 | 174 | depth: true, |
| 175 | + queueTimestamp: true, |
| 176 | + queue: true, |
171 | 177 | }, |
172 | 178 | }, |
173 | 179 | }, |
@@ -224,6 +230,8 @@ export class TriggerTaskServiceV1 extends BaseService { |
224 | 230 | taskIdentifier: true, |
225 | 231 | rootTaskRunId: true, |
226 | 232 | depth: true, |
| 233 | + queueTimestamp: true, |
| 234 | + queue: true, |
227 | 235 | }, |
228 | 236 | }, |
229 | 237 | }, |
@@ -276,7 +284,7 @@ export class TriggerTaskServiceV1 extends BaseService { |
276 | 284 | : undefined; |
277 | 285 |
|
278 | 286 | try { |
279 | | - return await eventRepository.traceEvent( |
| 287 | + const result = await eventRepository.traceEvent( |
280 | 288 | taskId, |
281 | 289 | { |
282 | 290 | context: options.traceContext, |
@@ -349,6 +357,12 @@ export class TriggerTaskServiceV1 extends BaseService { |
349 | 357 | ? dependentBatchRun.dependentTaskAttempt.taskRun.depth + 1 |
350 | 358 | : 0; |
351 | 359 |
|
| 360 | + const queueTimestamp = |
| 361 | + dependentAttempt?.taskRun.queueTimestamp ?? |
| 362 | + dependentBatchRun?.dependentTaskAttempt?.taskRun.queueTimestamp ?? |
| 363 | + delayUntil ?? |
| 364 | + new Date(); |
| 365 | + |
352 | 366 | const taskRun = await tx.taskRun.create({ |
353 | 367 | data: { |
354 | 368 | status: delayUntil ? "DELAYED" : "PENDING", |
@@ -376,7 +390,9 @@ export class TriggerTaskServiceV1 extends BaseService { |
376 | 390 | isTest: body.options?.test ?? false, |
377 | 391 | delayUntil, |
378 | 392 | queuedAt: delayUntil ? undefined : new Date(), |
| 393 | + queueTimestamp, |
379 | 394 | maxAttempts: body.options?.maxAttempts, |
| 395 | + taskEventStore: getTaskEventStore(), |
380 | 396 | ttl, |
381 | 397 | tags: |
382 | 398 | tagIds.length === 0 |
@@ -528,44 +544,61 @@ export class TriggerTaskServiceV1 extends BaseService { |
528 | 544 | this._prisma |
529 | 545 | ); |
530 | 546 |
|
531 | | - //release the concurrency for the env and org, if part of a (batch)triggerAndWait |
532 | | - if (dependentAttempt) { |
533 | | - const isSameTask = dependentAttempt.taskRun.taskIdentifier === taskId; |
534 | | - await marqs?.releaseConcurrency(dependentAttempt.taskRun.id, isSameTask); |
535 | | - } |
536 | | - if (dependentBatchRun?.dependentTaskAttempt) { |
537 | | - const isSameTask = |
538 | | - dependentBatchRun.dependentTaskAttempt.taskRun.taskIdentifier === taskId; |
539 | | - await marqs?.releaseConcurrency( |
540 | | - dependentBatchRun.dependentTaskAttempt.taskRun.id, |
541 | | - isSameTask |
542 | | - ); |
543 | | - } |
544 | | - |
545 | 547 | if (!run) { |
546 | 548 | return; |
547 | 549 | } |
548 | 550 |
|
549 | | - // We need to enqueue the task run into the appropriate queue. This is done after the tx completes to prevent a race condition where the task run hasn't been created yet by the time we dequeue. |
| 551 | + // Now enqueue the run if it's not delayed |
550 | 552 | if (run.status === "PENDING") { |
551 | | - await marqs?.enqueueMessage( |
552 | | - environment, |
553 | | - run.queue, |
554 | | - run.id, |
555 | | - { |
556 | | - type: "EXECUTE", |
557 | | - taskIdentifier: taskId, |
558 | | - projectId: environment.projectId, |
559 | | - environmentId: environment.id, |
560 | | - environmentType: environment.type, |
561 | | - }, |
562 | | - body.options?.concurrencyKey |
563 | | - ); |
| 553 | + const enqueueResult = await enqueueRun({ |
| 554 | + env: environment, |
| 555 | + run, |
| 556 | + dependentRun: |
| 557 | + dependentAttempt?.taskRun ?? dependentBatchRun?.dependentTaskAttempt?.taskRun, |
| 558 | + }); |
| 559 | + |
| 560 | + if (!enqueueResult.ok) { |
| 561 | + // Now we need to fail the run with enqueueResult.error and make sure and |
| 562 | + // set the traced event to failed as well |
| 563 | + await this._prisma.taskRun.update({ |
| 564 | + where: { id: run.id }, |
| 565 | + data: { |
| 566 | + status: "SYSTEM_FAILURE", |
| 567 | + completedAt: new Date(), |
| 568 | + error: enqueueResult.error, |
| 569 | + }, |
| 570 | + }); |
| 571 | + |
| 572 | + event.failWithError(enqueueResult.error); |
| 573 | + |
| 574 | + return { |
| 575 | + run, |
| 576 | + isCached: false, |
| 577 | + error: enqueueResult.error, |
| 578 | + }; |
| 579 | + } |
564 | 580 | } |
565 | 581 |
|
566 | 582 | return { run, isCached: false }; |
567 | 583 | } |
568 | 584 | ); |
| 585 | + |
| 586 | + if (result?.error) { |
| 587 | + throw new ServiceValidationError( |
| 588 | + taskRunErrorToString(taskRunErrorEnhancer(result.error)) |
| 589 | + ); |
| 590 | + } |
| 591 | + |
| 592 | + const run = result?.run; |
| 593 | + |
| 594 | + if (!run) { |
| 595 | + return; |
| 596 | + } |
| 597 | + |
| 598 | + return { |
| 599 | + run, |
| 600 | + isCached: result?.isCached, |
| 601 | + }; |
569 | 602 | } catch (error) { |
570 | 603 | // Detect a prisma transaction Unique constraint violation |
571 | 604 | if (error instanceof Prisma.PrismaClientKnownRequestError) { |
|
0 commit comments