@@ -378,6 +378,71 @@ process.on("message", (message) => {
378378 await expect ( provider . close ?.( ) ) . resolves . toBeUndefined ( ) ;
379379 } ) ;
380380
381+ it ( "terminates the worker when close runs behind a pending request" , async ( ) => {
382+ const tempDir = await fs . mkdtemp ( path . join ( os . tmpdir ( ) , "openclaw-local-embedding-worker-" ) ) ;
383+ const workerScript = path . join ( tempDir , "worker.cjs" ) ;
384+ const embedStartedPath = path . join ( tempDir , "embed-started" ) ;
385+ await fs . writeFile (
386+ workerScript ,
387+ `
388+ const fs = require("node:fs");
389+ const embedStartedPath = ${ JSON . stringify ( embedStartedPath ) } ;
390+ let busy = false;
391+
392+ process.on("message", (message) => {
393+ if (busy) {
394+ return;
395+ }
396+ if (message.type === "initialize") {
397+ process.send({ id: message.id, ok: true });
398+ return;
399+ }
400+ if (message.type === "embedQuery") {
401+ busy = true;
402+ fs.writeFileSync(embedStartedPath, "1");
403+ }
404+ });
405+ ` ,
406+ "utf8" ,
407+ ) ;
408+ const provider = await createLocalEmbeddingWorkerProvider (
409+ {
410+ config : { } as never ,
411+ provider : "local" ,
412+ model : "" ,
413+ fallback : "none" ,
414+ } ,
415+ { workerScriptPath : workerScript } ,
416+ ) ;
417+
418+ const embedPromise = provider . embedQuery ( "stuck" ) ;
419+ const embedError = embedPromise . then (
420+ ( ) => undefined ,
421+ ( err ) => err ,
422+ ) ;
423+ await expect
424+ . poll ( async ( ) => {
425+ try {
426+ await fs . access ( embedStartedPath ) ;
427+ return true ;
428+ } catch {
429+ return false ;
430+ }
431+ } )
432+ . toBe ( true ) ;
433+
434+ const closePromise = provider . close ?.( ) ?? Promise . resolve ( ) ;
435+ const closeResult = await Promise . race ( [
436+ closePromise . then ( ( ) => "closed" as const ) ,
437+ new Promise < "timeout" > ( ( resolve ) => setTimeout ( ( ) => resolve ( "timeout" ) , 1_000 ) ) ,
438+ ] ) ;
439+
440+ expect ( closeResult ) . toBe ( "closed" ) ;
441+ await expect ( embedError ) . resolves . toMatchObject ( {
442+ code : LOCAL_EMBEDDING_WORKER_ERROR_CODES . exited ,
443+ } ) ;
444+ } ) ;
445+
381446 it ( "does not pass inline-source or inspector exec args to the file-backed worker" , async ( ) => {
382447 const tempDir = await fs . mkdtemp ( path . join ( os . tmpdir ( ) , "openclaw-local-embedding-worker-" ) ) ;
383448 const workerScript = path . join ( tempDir , "worker.cjs" ) ;
0 commit comments