@@ -87,10 +87,6 @@ export class RunExecution {
8787 throw new Error ( "prepareForExecution called after process was already created" ) ;
8888 }
8989
90- if ( this . isPreparedForNextRun ) {
91- throw new Error ( "prepareForExecution called after execution was already prepared" ) ;
92- }
93-
9490 this . taskRunProcess = this . createTaskRunProcess ( {
9591 envVars : opts . taskRunEnv ,
9692 isWarmStart : true ,
@@ -151,9 +147,14 @@ export class RunExecution {
151147 }
152148
153149 /**
154- * Returns true if the execution has been prepared with task run env .
150+ * Returns true if no run has been started yet and the process is prepared for the next run .
155151 */
156- get isPreparedForNextRun ( ) : boolean {
152+ get canExecute ( ) : boolean {
153+ // If we've ever had a run ID, this execution can't be reused
154+ if ( this . _runFriendlyId ) {
155+ return false ;
156+ }
157+
157158 return ! ! this . taskRunProcess ?. isPreparedForNextRun ;
158159 }
159160
@@ -609,8 +610,18 @@ export class RunExecution {
609610 metrics : TaskRunExecutionMetrics ;
610611 isWarmStart ?: boolean ;
611612 } ) {
613+ // For immediate retries, we need to ensure the task run process is prepared for the next attempt
614+ if (
615+ this . runFriendlyId &&
616+ this . taskRunProcess &&
617+ ! this . taskRunProcess . isPreparedForNextAttempt
618+ ) {
619+ this . sendDebugLog ( "killing existing task run process before executing next attempt" ) ;
620+ await this . kill ( ) . catch ( ( ) => { } ) ;
621+ }
622+
612623 // To skip this step and eagerly create the task run process, run prepareForExecution first
613- if ( ! this . taskRunProcess || ! this . isPreparedForNextRun ) {
624+ if ( ! this . taskRunProcess || ! this . taskRunProcess . isPreparedForNextRun ) {
614625 this . taskRunProcess = this . createTaskRunProcess ( { envVars, isWarmStart } ) ;
615626 }
616627
@@ -667,11 +678,15 @@ export class RunExecution {
667678 }
668679
669680 public exit ( ) {
670- if ( this . isPreparedForNextRun ) {
681+ if ( this . taskRunProcess ?. isPreparedForNextRun ) {
671682 this . taskRunProcess ?. forceExit ( ) ;
672683 }
673684 }
674685
686+ public async kill ( ) {
687+ await this . taskRunProcess ?. kill ( "SIGKILL" ) ;
688+ }
689+
675690 private async complete ( { completion } : { completion : TaskRunExecutionResult } ) : Promise < void > {
676691 if ( ! this . runFriendlyId || ! this . currentSnapshotId ) {
677692 throw new Error ( "Cannot complete run: missing run or snapshot ID" ) ;
0 commit comments