@@ -26,7 +26,7 @@ export enum WorkerStatus {
2626
2727export class WorkerPool {
2828 #workers: Worker [ ] ;
29- #promises: Map < number , MessagePromise > ;
29+ #promises: Map < string , MessagePromise > ;
3030 #timeOfPreviousHeartbeat: Map < number , number > ;
3131 #which: number ;
3232
@@ -36,25 +36,37 @@ export class WorkerPool {
3636 for ( let i = 0 ; i < size ; i ++ ) {
3737 this . #workers[ i ] = new Worker ( workerModule , { type : 'module' } ) ;
3838 this . #workers[ i ] . onmessage = ( msg ) => this . #handleMessage( i , msg ) ;
39- this . #timeOfPreviousHeartbeat. set ( i , Date . now ( ) ) ;
39+ this . #timeOfPreviousHeartbeat. set ( i , 0 ) ;
4040 }
4141 this . #promises = new Map ( ) ;
4242 this . #which = 0 ;
4343 }
44-
44+ /**
45+ * Warning - nothing in this class should be considered useable after
46+ * calling this method - any/all methods called should be expected to be
47+ * completely unreliable. dont call me unless you're about to dispose of all references to this object
48+ */
49+ destroy ( ) {
50+ for ( let i = 0 ; i < this . #workers. length ; i ++ ) {
51+ this . #workers[ i ] . terminate ( ) ;
52+ }
53+ this . #workers = [ ] ;
54+ }
4555 #handleMessage( workerIndex : number , msg : MessageEvent < unknown > ) {
4656 const { data } = msg ;
47- const messagePromise = this . #promises. get ( workerIndex ) ;
4857 if ( isHeartbeatMessage ( data ) ) {
4958 this . #timeOfPreviousHeartbeat. set ( workerIndex , Date . now ( ) ) ;
5059 return ;
5160 }
52- if ( messagePromise === undefined ) {
53- logger . warn ( 'unexpected message from worker' ) ;
54- return ;
55- }
5661 if ( isWorkerMessageWithId ( data ) ) {
57- this . #promises. delete ( workerIndex ) ;
62+ logger . debug ( `worker ${ workerIndex } responded to a message` ) ;
63+ const { id } = data ;
64+ const messagePromise = this . #promises. get ( id ) ;
65+ if ( messagePromise === undefined ) {
66+ logger . warn ( 'unexpected message from worker' ) ;
67+ return ;
68+ }
69+ this . #promises. delete ( id ) ;
5870 if ( ! messagePromise . validator ( data ) ) {
5971 const reason = 'invalid response from worker: message type did not match expected type' ;
6072 logger . error ( reason ) ;
@@ -63,28 +75,32 @@ export class WorkerPool {
6375 }
6476 messagePromise . resolve ( data ) ;
6577 } else {
78+ logger . debug ( `worker ${ workerIndex } received an invalid message` ) ;
6679 const reason = 'encountered an invalid message; skipping' ;
67- logger . error ( reason ) ;
68- messagePromise . reject ( new Error ( reason ) ) ;
80+ logger . warn ( reason ) ;
6981 }
7082 }
7183
7284 #roundRobin( ) {
7385 this . #which = ( this . #which + 1 ) % this . #workers. length ;
7486 }
7587
76- submitRequest (
88+ async submitRequest (
7789 message : WorkerMessage ,
7890 responseValidator : MessageValidator < WorkerMessageWithId > ,
7991 transfers : Transferable [ ] ,
8092 signal ?: AbortSignal | undefined ,
8193 ) : Promise < WorkerMessageWithId > {
94+ if ( this . #workers. length < 1 ) {
95+ return Promise . reject ( 'this woorker pool has been disposed' ) ;
96+ }
8297 const reqId = `rq${ uuidv4 ( ) } ` ;
8398 const workerIndex = this . #which;
8499 const messageWithId = { ...message , id : reqId } ;
85100 const messagePromise = this . #createMessagePromise( responseValidator ) ;
101+ logger . debug ( `worker ${ workerIndex } being handed a request` ) ;
86102
87- this . #promises. set ( workerIndex , messagePromise ) ;
103+ this . #promises. set ( reqId , messagePromise ) ;
88104
89105 if ( signal ) {
90106 signal . addEventListener ( 'abort' , ( ) => {
@@ -126,7 +142,11 @@ export class WorkerPool {
126142 if ( ! this . #isValidIndex( workerIndex ) ) {
127143 throw new Error ( 'invalid worker index' ) ;
128144 }
129- const delta = Date . now ( ) - ( this . #timeOfPreviousHeartbeat. get ( workerIndex ) ?? 0 ) ;
145+ const lastHeartbeat = this . #timeOfPreviousHeartbeat. get ( workerIndex ) ?? 0 ;
146+ if ( lastHeartbeat === 0 ) {
147+ return WorkerStatus . Unresponsive ;
148+ }
149+ const delta = Date . now ( ) - lastHeartbeat ;
130150 if ( delta && delta > 1500 ) {
131151 return WorkerStatus . Unresponsive ;
132152 }
0 commit comments