@@ -35,10 +35,26 @@ export class TaskRunProcessProvider {
3535 this . processKeepAliveMaxExecutionCount = opts . processKeepAliveMaxExecutionCount ;
3636 }
3737
38+ async handleImmediateRetry ( ) : Promise < void > {
39+ if ( ! this . processKeepAliveEnabled ) {
40+ // For immediate retries, we need to ensure we have a clean process
41+ if ( this . persistentProcess ) {
42+ // If the process is not prepared for the next attempt, we need to get a fresh one
43+ if ( ! this . persistentProcess . isPreparedForNextAttempt ) {
44+ this . sendDebugLog (
45+ "existing task run process not prepared for retry, will get fresh process"
46+ ) ;
47+ await this . persistentProcess . kill ( "SIGKILL" ) ;
48+ this . persistentProcess = null ;
49+ }
50+ }
51+ }
52+ }
53+
3854 /**
3955 * Gets a TaskRunProcess, either by reusing an existing one or creating a new one
4056 */
41- getProcess ( opts : GetProcessOptions ) : TaskRunProcess {
57+ async getProcess ( opts : GetProcessOptions ) : Promise < TaskRunProcess > {
4258 this . sendDebugLog ( "Getting TaskRunProcess" , {
4359 processKeepAliveEnabled : this . processKeepAliveEnabled ,
4460 hasPersistentProcess : ! ! this . persistentProcess ,
@@ -47,16 +63,22 @@ export class TaskRunProcessProvider {
4763 isWarmStart : opts . isWarmStart ,
4864 } ) ;
4965
66+ // If process keep-alive is disabled, always create a new process
67+ if ( ! this . processKeepAliveEnabled ) {
68+ this . sendDebugLog ( "Creating new TaskRunProcess (keep-alive disabled)" ) ;
69+ return this . createTaskRunProcess ( opts ) ;
70+ }
71+
5072 // If process keep-alive is enabled and we have a healthy persistent process, reuse it
51- if ( this . processKeepAliveEnabled && this . shouldReusePersistentProcess ( ) ) {
73+ if ( this . shouldReusePersistentProcess ( ) ) {
5274 this . sendDebugLog ( "Reusing persistent TaskRunProcess" , {
5375 executionCount : this . executionCount ,
5476 } ) ;
5577
5678 return this . persistentProcess ! ;
5779 }
5880
59- // Create new process
81+ // Create new process (keep-alive enabled but no reusable process available)
6082 this . sendDebugLog ( "Creating new TaskRunProcess" , {
6183 hadPersistentProcess : ! ! this . persistentProcess ,
6284 reason : this . processKeepAliveEnabled
@@ -66,41 +88,69 @@ export class TaskRunProcessProvider {
6688
6789 // Clean up old persistent process if it exists
6890 if ( this . persistentProcess ) {
69- this . cleanupPersistentProcess ( ) ;
91+ await this . cleanupPersistentProcess ( ) ;
7092 }
7193
7294 const newProcess = this . createTaskRunProcess ( opts ) ;
7395 return newProcess ;
7496 }
7597
7698 /**
77- * Returns a process after execution, handling keep-alive logic
99+ * Returns a process after execution, handling keep-alive logic and cleanup
78100 */
79- returnProcess ( process : TaskRunProcess ) : void {
101+ async returnProcess ( process : TaskRunProcess ) : Promise < void > {
102+ this . sendDebugLog ( "Returning TaskRunProcess" , {
103+ processKeepAliveEnabled : this . processKeepAliveEnabled ,
104+ executionCount : this . executionCount ,
105+ maxExecutionCount : this . processKeepAliveMaxExecutionCount ,
106+ } ) ;
107+
80108 if ( ! this . processKeepAliveEnabled ) {
81- this . sendDebugLog ( "Keep-alive disabled, not preserving process" ) ;
109+ // Keep-alive disabled - immediately cleanup the process
110+ this . sendDebugLog ( "Keep-alive disabled, cleaning up process immediately" ) ;
111+ await process . cleanup ( true ) ;
82112 return ;
83113 }
84114
115+ // Keep-alive enabled - check if we should keep the process alive
85116 if ( this . shouldKeepProcessAlive ( process ) ) {
86117 this . sendDebugLog ( "Keeping TaskRunProcess alive for next run" , {
87118 executionCount : this . executionCount ,
88119 maxExecutionCount : this . processKeepAliveMaxExecutionCount ,
89120 } ) ;
90121
122+ // Call cleanup(false) to prepare for next run but keep process alive
123+ await process . cleanup ( false ) ;
91124 this . persistentProcess = process ;
92125 this . executionCount ++ ;
93126 } else {
94- this . sendDebugLog ( "Not keeping TaskRunProcess alive" , {
127+ this . sendDebugLog ( "Not keeping TaskRunProcess alive, cleaning up " , {
95128 executionCount : this . executionCount ,
96129 maxExecutionCount : this . processKeepAliveMaxExecutionCount ,
97130 isHealthy : this . isProcessHealthy ( process ) ,
98131 } ) ;
99132
100- // Don't set as persistent, it will be cleaned up normally
133+ // Cleanup the process completely
134+ await process . cleanup ( true ) ;
101135 }
102136 }
103137
138+ /**
139+ * Handles process abort/kill scenarios
140+ */
141+ async handleProcessAbort ( process : TaskRunProcess ) : Promise < void > {
142+ this . sendDebugLog ( "Handling process abort" ) ;
143+
144+ // If this was our persistent process, clear it
145+ if ( this . persistentProcess ?. pid === process . pid ) {
146+ this . persistentProcess = null ;
147+ this . executionCount = 0 ;
148+ }
149+
150+ // Kill the process
151+ await process . cleanup ( true ) ;
152+ }
153+
104154 /**
105155 * Forces cleanup of any persistent process
106156 */
@@ -173,12 +223,12 @@ export class TaskRunProcessProvider {
173223 return process . isPreparedForNextRun || process . isPreparedForNextAttempt ;
174224 }
175225
176- private cleanupPersistentProcess ( ) : void {
226+ private async cleanupPersistentProcess ( ) : Promise < void > {
177227 if ( this . persistentProcess ) {
178228 this . sendDebugLog ( "Cleaning up persistent TaskRunProcess" ) ;
179229
180230 // Don't await this - let it cleanup in the background
181- this . persistentProcess . kill ( "SIGKILL" ) . catch ( ( ) => { } ) ;
231+ await this . persistentProcess . kill ( "SIGKILL" ) . catch ( ( ) => { } ) ;
182232 this . persistentProcess = null ;
183233 this . executionCount = 0 ;
184234 }
0 commit comments