File tree Expand file tree Collapse file tree 2 files changed +16
-7
lines changed Expand file tree Collapse file tree 2 files changed +16
-7
lines changed Original file line number Diff line number Diff line change @@ -264,8 +264,10 @@ describe("Semaphore", () => {
264
264
} , delay ) ;
265
265
266
266
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
+ ) ,
269
271
270
272
semaphore
271
273
. tryAcquire ( delay * 2 , 3 )
@@ -286,7 +288,7 @@ describe("Semaphore", () => {
286
288
} )
287
289
] ) ;
288
290
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)
290
292
expect ( semaphore . permitsAvailable ) . toBe ( 1 ) ;
291
293
expect ( semaphore . permitsRequired ) . toBe ( 0 ) ;
292
294
expect ( semaphore . queueLength ) . toBe ( 0 ) ;
Original file line number Diff line number Diff line change @@ -142,15 +142,22 @@ export class Semaphore implements Synchronizer {
142
142
const { reject, resolvers } = item ;
143
143
144
144
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
149
146
const index = this . queue . findIndex ( i => i === item ) ;
150
147
if ( index >= 0 ) {
151
148
this . queue . splice ( index , 1 ) ;
152
149
}
153
150
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
+
154
161
reject (
155
162
new ConcurrencyExceedTimeoutException (
156
163
`Timeout of ${ timeout } ms exceed when acquiring.`
You can’t perform that action at this time.
0 commit comments