@@ -8,8 +8,10 @@ import {
88} from "@opennextjs/aws/utils/error.js" ;
99import { DurableObject } from "cloudflare:workers" ;
1010
11- const MAX_REVALIDATION_BY_DURABLE_OBJECT = 5 ;
11+ const DEFAULT_MAX_REVALIDATION_BY_DURABLE_OBJECT = 5 ;
1212const DEFAULT_REVALIDATION_TIMEOUT_MS = 10_000 ;
13+ const DEFAULT_REVALIDATION_RETRY_INTERVAL_MS = 2_000 ;
14+ const DEFAULT_MAX_REVALIDATION_ATTEMPTS = 6 ;
1315
1416interface FailedState {
1517 msg : QueueMessage ;
@@ -29,8 +31,11 @@ export class DurableObjectQueueHandler extends DurableObject<CloudflareEnv> {
2931
3032 service : NonNullable < CloudflareEnv [ "NEXT_CACHE_REVALIDATION_WORKER" ] > ;
3133
32- // TODO: allow this to be configurable - How do we want todo that? env variable? passed down from the queue override ?
33- maxRevalidations = MAX_REVALIDATION_BY_DURABLE_OBJECT ;
34+ // Configurable params
35+ maxRevalidations = DEFAULT_MAX_REVALIDATION_BY_DURABLE_OBJECT ;
36+ revalidationTimeout = DEFAULT_REVALIDATION_TIMEOUT_MS ;
37+ revalidationRetryInterval = DEFAULT_REVALIDATION_RETRY_INTERVAL_MS ;
38+ maxRevalidationAttempts = DEFAULT_MAX_REVALIDATION_ATTEMPTS ;
3439
3540 constructor ( ctx : DurableObjectState , env : CloudflareEnv ) {
3641 super ( ctx , env ) ;
@@ -41,6 +46,22 @@ export class DurableObjectQueueHandler extends DurableObject<CloudflareEnv> {
4146
4247 // We restore the state
4348 ctx . blockConcurrencyWhile ( ( ) => this . initState ( ) ) ;
49+
50+ this . maxRevalidations = env . MAX_REVALIDATION_BY_DURABLE_OBJECT
51+ ? parseInt ( env . MAX_REVALIDATION_BY_DURABLE_OBJECT )
52+ : DEFAULT_MAX_REVALIDATION_BY_DURABLE_OBJECT ;
53+
54+ this . revalidationTimeout = env . REVALIDATION_TIMEOUT_MS
55+ ? parseInt ( env . REVALIDATION_TIMEOUT_MS )
56+ : DEFAULT_REVALIDATION_TIMEOUT_MS ;
57+
58+ this . revalidationRetryInterval = env . REVALIDATION_RETRY_INTERVAL_MS
59+ ? parseInt ( env . REVALIDATION_RETRY_INTERVAL_MS )
60+ : DEFAULT_REVALIDATION_RETRY_INTERVAL_MS ;
61+
62+ this . maxRevalidationAttempts = env . MAX_REVALIDATION_ATTEMPTS
63+ ? parseInt ( env . MAX_REVALIDATION_ATTEMPTS )
64+ : DEFAULT_MAX_REVALIDATION_ATTEMPTS ;
4465 }
4566
4667 async revalidate ( msg : QueueMessage ) {
@@ -50,7 +71,7 @@ export class DurableObjectQueueHandler extends DurableObject<CloudflareEnv> {
5071 // The route is already in a failed state, it will be retried later
5172 if ( this . routeInFailedState . has ( msg . MessageDeduplicationId ) ) return ;
5273
53- if ( this . ongoingRevalidations . size >= MAX_REVALIDATION_BY_DURABLE_OBJECT ) {
74+ if ( this . ongoingRevalidations . size >= this . maxRevalidations ) {
5475 const ongoingRevalidations = this . ongoingRevalidations . values ( ) ;
5576 // When there is more than the max revalidations, we block concurrency until one of the revalidations finishes
5677 // We still await the promise to ensure the revalidation is completed
@@ -81,7 +102,7 @@ export class DurableObjectQueueHandler extends DurableObject<CloudflareEnv> {
81102 "x-prerender-revalidate" : process . env . __NEXT_PREVIEW_MODE_ID ! ,
82103 "x-isr" : "1" ,
83104 } ,
84- signal : AbortSignal . timeout ( DEFAULT_REVALIDATION_TIMEOUT_MS ) ,
105+ signal : AbortSignal . timeout ( this . revalidationTimeout ) ,
85106 } ) ;
86107 // Now we need to handle errors from the fetch
87108 if ( response . status === 200 && response . headers . get ( "x-nextjs-cache" ) !== "REVALIDATED" ) {
@@ -156,15 +177,15 @@ export class DurableObjectQueueHandler extends DurableObject<CloudflareEnv> {
156177 let updatedFailedState : FailedState ;
157178
158179 if ( existingFailedState ) {
159- if ( existingFailedState . retryCount >= 6 ) {
180+ if ( existingFailedState . retryCount >= this . maxRevalidationAttempts ) {
160181 // We give up after 6 retries and log the error
161182 error (
162183 `The revalidation for ${ msg . MessageBody . host } ${ msg . MessageBody . url } has failed after 6 retries. It will not be tried again, but subsequent ISR requests will retry.`
163184 ) ;
164185 this . routeInFailedState . delete ( msg . MessageDeduplicationId ) ;
165186 return ;
166187 }
167- const nextAlarmMs = Date . now ( ) + Math . pow ( 2 , existingFailedState . retryCount + 1 ) * 2_000 ;
188+ const nextAlarmMs = Date . now ( ) + Math . pow ( 2 , existingFailedState . retryCount + 1 ) * this . revalidationRetryInterval ;
168189 updatedFailedState = {
169190 ...existingFailedState ,
170191 retryCount : existingFailedState . retryCount + 1 ,
@@ -198,7 +219,7 @@ export class DurableObjectQueueHandler extends DurableObject<CloudflareEnv> {
198219 ) ;
199220 if ( nextAlarmToSetup < Date . now ( ) ) {
200221 // We don't want to set an alarm in the past
201- nextAlarmToSetup = Date . now ( ) + 2_000 ;
222+ nextAlarmToSetup = Date . now ( ) + this . revalidationRetryInterval ;
202223 }
203224 await this . ctx . storage . setAlarm ( nextAlarmToSetup ) ;
204225 }
0 commit comments