@@ -29,30 +29,44 @@ export async function getReaper(client: ContainerRuntimeClient): Promise<Reaper>
2929 }
3030
3131 reaper = await withFileLock ( "testcontainers-node.lock" , async ( ) => {
32- const reaperContainer = await findReaperContainer ( client ) ;
33- sessionId = reaperContainer ?. Labels [ LABEL_TESTCONTAINERS_SESSION_ID ] ?? new RandomUuid ( ) . nextUuid ( ) ;
32+ const reaperContainers = await findReaperContainers ( client ) ;
3433
3534 if ( process . env . TESTCONTAINERS_RYUK_DISABLED === "true" ) {
35+ sessionId = new RandomUuid ( ) . nextUuid ( ) ;
3636 return new DisabledReaper ( sessionId , "" ) ;
37- } else if ( reaperContainer ) {
38- return await useExistingReaper ( reaperContainer , sessionId , client . info . containerRuntime . host ) ;
39- } else {
40- return await createNewReaper ( sessionId , client . info . containerRuntime . remoteSocketPath ) ;
4137 }
38+
39+ for ( const reaperContainer of reaperContainers ) {
40+ const existingSessionId = reaperContainer . Labels [ LABEL_TESTCONTAINERS_SESSION_ID ] ?? new RandomUuid ( ) . nextUuid ( ) ;
41+ try {
42+ sessionId = existingSessionId ;
43+ return await useExistingReaper ( reaperContainer , sessionId , client . info . containerRuntime . host ) ;
44+ } catch ( error ) {
45+ const message = error instanceof Error ? error . message : String ( error ) ;
46+ log . warn ( `Failed to reuse existing Reaper: ${ message } . Trying another Reaper...` , {
47+ containerId : reaperContainer . Id ,
48+ } ) ;
49+ }
50+ }
51+
52+ sessionId = new RandomUuid ( ) . nextUuid ( ) ;
53+ return await createNewReaper ( sessionId , client . info . containerRuntime . remoteSocketPath ) ;
4254 } ) ;
4355
4456 reaper . addSession ( sessionId ) ;
4557 return reaper ;
4658}
4759
48- async function findReaperContainer ( client : ContainerRuntimeClient ) : Promise < ContainerInfo | undefined > {
60+ async function findReaperContainers ( client : ContainerRuntimeClient ) : Promise < ContainerInfo [ ] > {
4961 const containers = await client . container . list ( ) ;
50- return containers . find (
51- ( container ) =>
52- container . State === "running" &&
53- container . Labels [ LABEL_TESTCONTAINERS_RYUK ] === "true" &&
54- container . Labels [ "TESTCONTAINERS_RYUK_TEST_LABEL" ] !== "true"
55- ) ;
62+ return containers
63+ . filter (
64+ ( container ) =>
65+ container . State === "running" &&
66+ container . Labels [ LABEL_TESTCONTAINERS_RYUK ] === "true" &&
67+ container . Labels [ "TESTCONTAINERS_RYUK_TEST_LABEL" ] !== "true"
68+ )
69+ . sort ( ( a , b ) => b . Created - a . Created ) ;
5670}
5771
5872async function useExistingReaper ( reaperContainer : ContainerInfo , sessionId : string , host : string ) : Promise < Reaper > {
0 commit comments