@@ -17,6 +17,7 @@ type PanelCloudflareTunnelRecord = {
1717 readonly homeDir : string
1818 logLines : ReadonlyArray < string >
1919 process : ChildProcess | null
20+ processClosed : boolean
2021 session : PanelCloudflareTunnelSession
2122 stderrRemainder : string
2223 stopFiber : Fiber . RuntimeFiber < PanelCloudflareTunnelSession > | null
@@ -150,6 +151,7 @@ const createStartingRecord = (
150151 homeDir,
151152 logLines : [ ] ,
152153 process : null ,
154+ processClosed : false ,
153155 session : {
154156 error : null ,
155157 id,
@@ -199,12 +201,16 @@ const finishStoppedRecord = (
199201 return session
200202}
201203
202- const waitForChildClose = ( child : ChildProcess ) : Effect . Effect < void > => {
203- if ( child . exitCode !== null || child . signalCode !== null ) {
204+ const waitForChildClose = (
205+ record : PanelCloudflareTunnelRecord ,
206+ child : ChildProcess
207+ ) : Effect . Effect < void > => {
208+ if ( record . processClosed ) {
204209 return Effect . void
205210 }
206211
207212 return Effect . async ( ( resume ) => {
213+ const alreadyExited = child . exitCode !== null || child . signalCode !== null
208214 let completed = false
209215 let killTimer : ReturnType < typeof setTimeout > | null = null
210216 const complete = ( ) : void => {
@@ -214,7 +220,6 @@ const waitForChildClose = (child: ChildProcess): Effect.Effect<void> => {
214220 completed = true
215221 child . off ( "close" , complete )
216222 child . off ( "error" , complete )
217- child . off ( "exit" , complete )
218223 if ( killTimer !== null ) {
219224 clearTimeout ( killTimer )
220225 }
@@ -223,25 +228,26 @@ const waitForChildClose = (child: ChildProcess): Effect.Effect<void> => {
223228
224229 child . once ( "close" , complete )
225230 child . once ( "error" , complete )
226- child . once ( "exit" , complete )
227- if ( ! child . killed ) {
231+ if ( ! alreadyExited && ! child . killed ) {
228232 try {
229233 child . kill ( "SIGTERM" )
230234 } catch {
231235 complete ( )
232236 return
233237 }
234238 }
235- killTimer = setTimeout ( ( ) => {
236- try {
237- if ( child . exitCode === null && child . signalCode === null ) {
238- child . kill ( "SIGKILL" )
239+ if ( ! alreadyExited ) {
240+ killTimer = setTimeout ( ( ) => {
241+ try {
242+ if ( child . exitCode === null && child . signalCode === null ) {
243+ child . kill ( "SIGKILL" )
244+ }
245+ } catch {
246+ complete ( )
239247 }
240- } catch {
241- complete ( )
242- }
243- } , 2_000 )
244- killTimer . unref ( )
248+ } , 2_000 )
249+ killTimer . unref ( )
250+ }
245251 } )
246252}
247253
@@ -255,7 +261,7 @@ const stopRecord = (
255261
256262 const child = record . process
257263 record . stopping = true
258- const stopFiber = Effect . runFork ( ( child === null ? Effect . void : waitForChildClose ( child ) ) . pipe (
264+ const stopFiber = Effect . runFork ( ( child === null ? Effect . void : waitForChildClose ( record , child ) ) . pipe (
259265 Effect . map ( ( ) => finishStoppedRecord ( record , error ) )
260266 ) )
261267 record . stopFiber = stopFiber
@@ -277,6 +283,7 @@ const attachProcessHandlers = (
277283 child : ChildProcess
278284) : void => {
279285 record . process = child
286+ record . processClosed = false
280287 child . stdout ?. on ( "data" , ( chunk : Buffer ) => {
281288 consumeChunk ( record , "stdout" , chunk )
282289 } )
@@ -287,6 +294,7 @@ const attachProcessHandlers = (
287294 runStopRecord ( record , `cloudflared failed to start: ${ error . message } ` )
288295 } )
289296 child . on ( "close" , ( exitCode , signal ) => {
297+ record . processClosed = true
290298 flushRemainder ( record , "stdout" )
291299 flushRemainder ( record , "stderr" )
292300 if ( record . stopping || record . session . status === "stopped" || record . session . status === "failed" ) {
0 commit comments