@@ -16,29 +16,27 @@ import { blobToUint8Array } from "@App/pkg/utils/datatype";
1616import { readBlobContent } from "@App/pkg/utils/encoding" ;
1717
1818class Semaphore {
19- private running = 0 ;
19+ private active = 0 ;
2020 private readonly queue : Array < ( ) => void > = [ ] ;
2121
2222 constructor ( readonly limit : number ) {
2323 if ( limit < 1 ) throw new Error ( "limit must be >= 1" ) ;
2424 }
2525
26- async acquire ( ) : Promise < void > {
27- if ( this . running < this . limit ) {
28- this . running ++ ;
29- return ;
26+ async acquire ( ) {
27+ if ( this . active >= this . limit ) {
28+ await new Promise < void > ( ( resolve ) => this . queue . push ( resolve ) ) ;
3029 }
31- await new Promise < void > ( ( resolve ) => this . queue . push ( resolve ) ) ;
32- this . running ++ ;
30+ this . active ++ ;
3331 }
3432
35- release ( ) : void {
36- if ( this . running <= 0 ) {
33+ release ( ) {
34+ if ( this . active > 0 ) {
35+ this . active -- ;
36+ this . queue . shift ( ) ?.( ) ;
37+ } else {
3738 console . warn ( "Semaphore double release detected" ) ;
38- return ;
3939 }
40- this . running -- ;
41- this . queue . shift ( ) ?.( ) ;
4240 }
4341}
4442
@@ -319,6 +317,7 @@ export class ResourceService {
319317 async createResourceByUrlFetch ( u : TUrlSRIInfo , type : ResourceType ) : Promise < Resource > {
320318 const url = u . url ; // 无 URI Integrity Hash
321319
320+ let released = false ;
322321 await fetchSemaphore . acquire ( ) ;
323322 // Semaphore 锁 - 同期只有五个 fetch 一起执行
324323 const delay = randNum ( 100 , 150 ) ; // 100~150ms delay before starting fetch
@@ -328,7 +327,10 @@ export class ResourceService {
328327 const { result, err } = await withTimeoutNotify ( fetch ( url ) , 800 , ( { done, timeouted, err } ) => {
329328 if ( timeouted || done || err ) {
330329 // fetch 成功 或 发生错误 或 timeout 时解锁
331- fetchSemaphore . release ( ) ;
330+ if ( ! released ) {
331+ released = true ;
332+ fetchSemaphore . release ( ) ;
333+ }
332334 }
333335 } ) ;
334336 // Semaphore 锁已解锁。继续处理 fetch Response 的结果
0 commit comments