66} from "@trigger.dev/core/v3" ;
77import { TaskRun } from "@trigger.dev/database" ;
88import { z } from "zod" ;
9+ import { prisma } from "~/db.server" ;
910import { env } from "~/env.server" ;
1011import { EngineServiceValidationError } from "~/runEngine/concerns/errors" ;
1112import {
@@ -14,6 +15,7 @@ import {
1415 getOneTimeUseToken ,
1516} from "~/services/apiAuth.server" ;
1617import { logger } from "~/services/logger.server" ;
18+ import { requestIdempotency } from "~/services/requestIdempotencyInstance.server" ;
1719import { createActionApiRoute } from "~/services/routeBuilders/apiBuilder.server" ;
1820import { resolveIdempotencyKeyTTL } from "~/utils/idempotencyKeys.server" ;
1921import { ServiceValidationError } from "~/v3/services/baseService.server" ;
@@ -31,6 +33,7 @@ export const HeadersSchema = z.object({
3133 "x-trigger-worker" : z . string ( ) . nullish ( ) ,
3234 "x-trigger-client" : z . string ( ) . nullish ( ) ,
3335 "x-trigger-engine-version" : RunEngineVersionSchema . nullish ( ) ,
36+ "x-trigger-request-id" : z . string ( ) . nullish ( ) ,
3437 traceparent : z . string ( ) . optional ( ) ,
3538 tracestate : z . string ( ) . optional ( ) ,
3639} ) ;
@@ -60,8 +63,53 @@ const { action, loader } = createActionApiRoute(
6063 "x-trigger-worker" : isFromWorker ,
6164 "x-trigger-client" : triggerClient ,
6265 "x-trigger-engine-version" : engineVersion ,
66+ "x-trigger-request-id" : requestId ,
6367 } = headers ;
6468
69+ if ( requestId ) {
70+ logger . debug ( "request-idempotency: checking for cached trigger request" , {
71+ requestId,
72+ } ) ;
73+
74+ const cachedRequest = await requestIdempotency . checkRequest ( "trigger" , requestId ) ;
75+
76+ if ( cachedRequest ) {
77+ logger . info ( "request-idempotency: found cached trigger request" , {
78+ requestId,
79+ cachedRequest,
80+ } ) ;
81+
82+ const cachedRun = await prisma . taskRun . findFirst ( {
83+ where : {
84+ id : cachedRequest . id ,
85+ } ,
86+ select : {
87+ friendlyId : true ,
88+ } ,
89+ } ) ;
90+
91+ if ( cachedRun ) {
92+ logger . info ( "request-idempotency: found cached trigger run" , {
93+ requestId,
94+ cachedRun,
95+ } ) ;
96+
97+ const $responseHeaders = await responseHeaders ( cachedRun , authentication , triggerClient ) ;
98+
99+ return json (
100+ {
101+ id : cachedRun . friendlyId ,
102+ isCached : false ,
103+ } ,
104+ {
105+ headers : $responseHeaders ,
106+ status : 200 ,
107+ }
108+ ) ;
109+ }
110+ }
111+ }
112+
65113 const service = new TriggerTaskService ( ) ;
66114
67115 try {
@@ -104,6 +152,12 @@ const { action, loader } = createActionApiRoute(
104152 return json ( { error : "Task not found" } , { status : 404 } ) ;
105153 }
106154
155+ if ( requestId ) {
156+ await requestIdempotency . saveRequest ( "trigger" , requestId , {
157+ id : result . run . id ,
158+ } ) ;
159+ }
160+
107161 const $responseHeaders = await responseHeaders ( result . run , authentication , triggerClient ) ;
108162
109163 return json (
@@ -113,6 +167,7 @@ const { action, loader } = createActionApiRoute(
113167 } ,
114168 {
115169 headers : $responseHeaders ,
170+ status : 200 ,
116171 }
117172 ) ;
118173 } catch ( error ) {
@@ -132,7 +187,7 @@ const { action, loader } = createActionApiRoute(
132187) ;
133188
134189async function responseHeaders (
135- run : TaskRun ,
190+ run : Pick < TaskRun , "friendlyId" > ,
136191 authentication : ApiAuthenticationResultSuccess ,
137192 triggerClient ?: string | null
138193) : Promise < Record < string , string > > {
0 commit comments