File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -264,8 +264,10 @@ describe("Semaphore", () => {
264264 } , delay ) ;
265265
266266 await Promise . all ( [
267- // second acquire in time
268- new Promise ( resolve => setTimeout ( resolve , 10 ) ) . then ( ( ) => semaphore . acquire ( 2 ) ) ,
267+ // `acquire` after the `tryAcquire`
268+ new Promise ( resolve => setTimeout ( resolve , delay / 2 ) ) . then ( ( ) =>
269+ semaphore . acquire ( 3 )
270+ ) ,
269271
270272 semaphore
271273 . tryAcquire ( delay * 2 , 3 )
@@ -286,7 +288,7 @@ describe("Semaphore", () => {
286288 } )
287289 ] ) ;
288290
289- // The state is reset: 2 permits released for a single successful acquire (+ the initial one)
291+ // The state is reset: 3 permits released for a single successful acquire (+ the initial one)
290292 expect ( semaphore . permitsAvailable ) . toBe ( 1 ) ;
291293 expect ( semaphore . permitsRequired ) . toBe ( 0 ) ;
292294 expect ( semaphore . queueLength ) . toBe ( 0 ) ;
Original file line number Diff line number Diff line change @@ -142,15 +142,22 @@ export class Semaphore implements Synchronizer {
142142 const { reject, resolvers } = item ;
143143
144144 setTimeout ( ( ) => {
145- // Re-establish th permits: the previous permits + the releases that were called during the wait
146- this . permits += permitsBck + ( permitsRemaining - resolvers . length ) ;
147-
148- // Removes the item form the queue
145+ // Remove the item from the queue
149146 const index = this . queue . findIndex ( i => i === item ) ;
150147 if ( index >= 0 ) {
151148 this . queue . splice ( index , 1 ) ;
152149 }
153150
151+ // Re-establish the permits: the previous permits + the releases that were called during the wait
152+ const permitsTaken = permitsBck + ( permitsRemaining - resolvers . length ) ;
153+ const permitsToRelease = Math . min ( permitsTaken , this . permitsRequired ) ;
154+
155+ this . permits += permitsTaken - permitsToRelease ;
156+ if ( permitsToRelease > 0 ) {
157+ // "free" the permits for this failed `tryLock`
158+ this . release ( permitsToRelease ) ;
159+ }
160+
154161 reject (
155162 new ConcurrencyExceedTimeoutException (
156163 `Timeout of ${ timeout } ms exceed when acquiring.`
You can’t perform that action at this time.
0 commit comments