File tree Expand file tree Collapse file tree 2 files changed +37
-3
lines changed
Expand file tree Collapse file tree 2 files changed +37
-3
lines changed Original file line number Diff line number Diff line change @@ -198,4 +198,26 @@ describe("inspectGatewayRestart", () => {
198198
199199 expect ( snapshot . healthy ) . toBe ( true ) ;
200200 } ) ;
201+
202+ it ( "treats busy ports with unavailable listener details as healthy when runtime is running" , async ( ) => {
203+ const service = {
204+ readRuntime : vi . fn ( async ( ) => ( { status : "running" , pid : 8000 } ) ) ,
205+ } as unknown as GatewayService ;
206+
207+ inspectPortUsage . mockResolvedValue ( {
208+ port : 18789 ,
209+ status : "busy" ,
210+ listeners : [ ] ,
211+ hints : [
212+ "Port is in use but process details are unavailable (install lsof or run as an admin user)." ,
213+ ] ,
214+ errors : [ "Error: spawn lsof ENOENT" ] ,
215+ } ) ;
216+
217+ const { inspectGatewayRestart } = await import ( "./restart-health.js" ) ;
218+ const snapshot = await inspectGatewayRestart ( { service, port : 18789 } ) ;
219+
220+ expect ( snapshot . healthy ) . toBe ( true ) ;
221+ expect ( probeGateway ) . not . toHaveBeenCalled ( ) ;
222+ } ) ;
201223} ) ;
Original file line number Diff line number Diff line change @@ -28,6 +28,16 @@ export type GatewayPortHealthSnapshot = {
2828 healthy : boolean ;
2929} ;
3030
31+ function hasListenerAttributionGap ( portUsage : PortUsage ) : boolean {
32+ if ( portUsage . status !== "busy" || portUsage . listeners . length > 0 ) {
33+ return false ;
34+ }
35+ if ( portUsage . errors ?. length ) {
36+ return true ;
37+ }
38+ return portUsage . hints . some ( ( hint ) => hint . includes ( "process details are unavailable" ) ) ;
39+ }
40+
3141function listenerOwnedByRuntimePid ( params : {
3242 listener : PortUsage [ "listeners" ] [ number ] ;
3343 runtimePid : number ;
@@ -131,11 +141,13 @@ export async function inspectGatewayRestart(params: {
131141 : [ ] ;
132142 const running = runtime . status === "running" ;
133143 const runtimePid = runtime . pid ;
144+ const listenerAttributionGap = hasListenerAttributionGap ( portUsage ) ;
134145 const ownsPort =
135146 runtimePid != null
136- ? portUsage . listeners . some ( ( listener ) => listenerOwnedByRuntimePid ( { listener, runtimePid } ) )
137- : gatewayListeners . length > 0 ||
138- ( portUsage . status === "busy" && portUsage . listeners . length === 0 ) ;
147+ ? portUsage . listeners . some ( ( listener ) =>
148+ listenerOwnedByRuntimePid ( { listener, runtimePid } ) ,
149+ ) || listenerAttributionGap
150+ : gatewayListeners . length > 0 || listenerAttributionGap ;
139151 let healthy = running && ownsPort ;
140152 if ( ! healthy && running && portUsage . status === "busy" ) {
141153 try {
You can’t perform that action at this time.
0 commit comments