@@ -66,15 +66,6 @@ export interface LockRetryConfig {
6666 maxTotalWaitTime ?: number ;
6767}
6868
69- interface LockOptions {
70- /** Default lock duration in milliseconds (default: 5000) */
71- defaultDuration ?: number ;
72- /** Automatic extension threshold in milliseconds - how early to extend locks before expiration (default: 500) */
73- automaticExtensionThreshold ?: number ;
74- /** Retry configuration for lock acquisition */
75- retryConfig ?: LockRetryConfig ;
76- }
77-
7869export class RunLocker {
7970 private redlock : InstanceType < typeof redlock . default > ;
8071 private asyncLocalStorage : AsyncLocalStorage < LockContext > ;
@@ -85,20 +76,20 @@ export class RunLocker {
8576 private activeManualContexts : Map < string , ManualLockContext > = new Map ( ) ;
8677 private lockDurationHistogram : Histogram ;
8778 private retryConfig : Required < LockRetryConfig > ;
88- private defaultDuration : number ;
79+ private duration : number ;
8980 private automaticExtensionThreshold : number ;
9081
9182 constructor ( options : {
9283 redis : Redis ;
9384 logger : Logger ;
9485 tracer : Tracer ;
9586 meter ?: Meter ;
96- defaultDuration ?: number ;
87+ duration ?: number ;
9788 automaticExtensionThreshold ?: number ;
9889 retryConfig ?: LockRetryConfig ;
9990 } ) {
10091 // Initialize configuration values
101- this . defaultDuration = options . defaultDuration ?? 5000 ;
92+ this . duration = options . duration ?? 5000 ;
10293 this . automaticExtensionThreshold = options . automaticExtensionThreshold ?? 500 ;
10394
10495 this . redlock = new Redlock ( [ options . redis ] , {
@@ -157,48 +148,18 @@ export class RunLocker {
157148 }
158149
159150 /** Locks resources using RedLock. It won't lock again if we're already inside a lock with the same resources. */
160- async lock < T > (
161- name : string ,
162- resources : string [ ] ,
163- duration : number | undefined ,
164- routine : ( signal : redlock . RedlockAbortSignal ) => Promise < T >
165- ) : Promise < T > ;
166- async lock < T > (
167- name : string ,
168- resources : string [ ] ,
169- routine : ( signal : redlock . RedlockAbortSignal ) => Promise < T >
170- ) : Promise < T > ;
171- async lock < T > (
172- name : string ,
173- resources : string [ ] ,
174- durationOrRoutine : number | undefined | ( ( signal : redlock . RedlockAbortSignal ) => Promise < T > ) ,
175- routine ?: ( signal : redlock . RedlockAbortSignal ) => Promise < T >
176- ) : Promise < T > {
151+ async lock < T > ( name : string , resources : string [ ] , routine : ( ) => Promise < T > ) : Promise < T > {
177152 const currentContext = this . asyncLocalStorage . getStore ( ) ;
178153 const joinedResources = [ ...resources ] . sort ( ) . join ( "," ) ;
179154
180- // Handle overloaded parameters
181- let actualDuration : number ;
182- let actualRoutine : ( signal : redlock . RedlockAbortSignal ) => Promise < T > ;
183-
184- if ( typeof durationOrRoutine === "function" ) {
185- // Called as lock(name, resources, routine) - use default duration
186- actualDuration = this . defaultDuration ;
187- actualRoutine = durationOrRoutine ;
188- } else {
189- // Called as lock(name, resources, duration, routine) - use provided duration
190- actualDuration = durationOrRoutine ?? this . defaultDuration ;
191- actualRoutine = routine ! ;
192- }
193-
194155 return startSpan (
195156 this . tracer ,
196157 "RunLocker.lock" ,
197158 async ( span ) => {
198159 if ( currentContext && currentContext . resources === joinedResources ) {
199160 span . setAttribute ( "nested" , true ) ;
200161 // We're already inside a lock with the same resources, just run the routine
201- return actualRoutine ( currentContext . signal ) ;
162+ return routine ( ) ;
202163 }
203164
204165 span . setAttribute ( "nested" , false ) ;
@@ -208,14 +169,7 @@ export class RunLocker {
208169 const lockStartTime = performance . now ( ) ;
209170
210171 const [ error , result ] = await tryCatch (
211- this . #acquireAndExecute(
212- name ,
213- resources ,
214- actualDuration ,
215- actualRoutine ,
216- lockId ,
217- lockStartTime
218- )
172+ this . #acquireAndExecute( name , resources , this . duration , routine , lockId , lockStartTime )
219173 ) ;
220174
221175 if ( error ) {
@@ -229,15 +183,15 @@ export class RunLocker {
229183 this . logger . error ( "[RunLocker] Error locking resources" , {
230184 error,
231185 resources,
232- duration : actualDuration ,
186+ duration : this . duration ,
233187 } ) ;
234188 throw error ;
235189 }
236190
237191 return result ;
238192 } ,
239193 {
240- attributes : { name, resources, timeout : actualDuration } ,
194+ attributes : { name, resources, timeout : this . duration } ,
241195 }
242196 ) ;
243197 }
@@ -247,7 +201,7 @@ export class RunLocker {
247201 name : string ,
248202 resources : string [ ] ,
249203 duration : number ,
250- routine : ( signal : redlock . RedlockAbortSignal ) => Promise < T > ,
204+ routine : ( ) => Promise < T > ,
251205 lockId : string ,
252206 lockStartTime : number
253207 ) : Promise < T > {
@@ -260,7 +214,6 @@ export class RunLocker {
260214 this . retryConfig ;
261215
262216 // Track timing for total wait time limit
263- const retryStartTime = performance . now ( ) ;
264217 let totalWaitTime = 0 ;
265218
266219 // Retry the lock acquisition with exponential backoff
@@ -398,7 +351,7 @@ export class RunLocker {
398351 let lockSuccess = true ;
399352 try {
400353 const result = await this . asyncLocalStorage . run ( newContext , async ( ) => {
401- return routine ( signal ) ;
354+ return routine ( ) ;
402355 } ) ;
403356
404357 return result ;
@@ -529,47 +482,12 @@ export class RunLocker {
529482 condition : boolean ,
530483 name : string ,
531484 resources : string [ ] ,
532- duration : number | undefined ,
533- routine : ( signal ?: redlock . RedlockAbortSignal ) => Promise < T >
534- ) : Promise < T > ;
535- async lockIf < T > (
536- condition : boolean ,
537- name : string ,
538- resources : string [ ] ,
539- routine : ( signal ?: redlock . RedlockAbortSignal ) => Promise < T >
540- ) : Promise < T > ;
541- async lockIf < T > (
542- condition : boolean ,
543- name : string ,
544- resources : string [ ] ,
545- durationOrRoutine : number | undefined | ( ( signal ?: redlock . RedlockAbortSignal ) => Promise < T > ) ,
546- routine ?: ( signal ?: redlock . RedlockAbortSignal ) => Promise < T >
485+ routine : ( ) => Promise < T >
547486 ) : Promise < T > {
548487 if ( condition ) {
549- // Handle overloaded parameters
550- if ( typeof durationOrRoutine === "function" ) {
551- // Called as lockIf(condition, name, resources, routine) - use default duration
552- return this . lock (
553- name ,
554- resources ,
555- durationOrRoutine as ( signal : redlock . RedlockAbortSignal ) => Promise < T >
556- ) ;
557- } else {
558- // Called as lockIf(condition, name, resources, duration, routine) - use provided duration
559- return this . lock (
560- name ,
561- resources ,
562- durationOrRoutine ,
563- routine ! as ( signal : redlock . RedlockAbortSignal ) => Promise < T >
564- ) ;
565- }
488+ return this . lock ( name , resources , routine ) ;
566489 } else {
567- // Handle overloaded parameters for non-lock case
568- if ( typeof durationOrRoutine === "function" ) {
569- return durationOrRoutine ( ) ;
570- } else {
571- return routine ! ( ) ;
572- }
490+ return routine ( ) ;
573491 }
574492 }
575493
@@ -585,8 +503,8 @@ export class RunLocker {
585503 return { ...this . retryConfig } ;
586504 }
587505
588- getDefaultDuration ( ) : number {
589- return this . defaultDuration ;
506+ getDuration ( ) : number {
507+ return this . duration ;
590508 }
591509
592510 getAutomaticExtensionThreshold ( ) : number {
0 commit comments