Skip to content

Commit fa4c9ae

Browse files
committed
fix: control active cleanup child jobs
1 parent a3c3c5f commit fa4c9ae

2 files changed

Lines changed: 55 additions & 12 deletions

File tree

inc/Cli/Commands/WorkspaceCommand.php

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -666,22 +666,56 @@ private function control_cleanup_run_job( string $operation, int $job_id, array
666666
return;
667667
}
668668

669-
$input = array( 'job_id' => $job_id );
670-
if ( 'resume' === $operation ) {
671-
$input['force'] = ! empty( $assoc_args['force'] );
672-
} else {
673-
$input['reason'] = 'cleanup_cancelled';
669+
$target_job_ids = $this->cleanup_run_control_job_ids( $operation, $job_id );
670+
$results = array();
671+
foreach ( $target_job_ids as $target_job_id ) {
672+
$input = array( 'job_id' => $target_job_id );
673+
if ( 'resume' === $operation ) {
674+
$input['force'] = ! empty( $assoc_args['force'] );
675+
} else {
676+
$input['reason'] = 'cleanup_cancelled';
677+
}
678+
679+
$result = $ability->execute( $input );
680+
if ( ! ( $result['success'] ?? false ) ) {
681+
WP_CLI::error( (string) ( $result['error'] ?? 'Cleanup run control failed.' ) );
682+
return;
683+
}
684+
$results[] = $result;
674685
}
675686

676-
$result = $ability->execute( $input );
677-
if ( ! ( $result['success'] ?? false ) ) {
678-
WP_CLI::error( (string) ( $result['error'] ?? 'Cleanup run control failed.' ) );
679-
return;
687+
$output = $results[0] ?? array( 'success' => true, 'job_id' => $job_id );
688+
$output['run_id'] = $this->cleanup_run_id( $job_id );
689+
$output['state'] = 'resume' === $operation ? 'running' : 'cancelled';
690+
$output['controlled_job_ids'] = $target_job_ids;
691+
$output['results'] = $results;
692+
$this->render_cleanup_control_result( $output, $assoc_args );
693+
}
694+
695+
/**
696+
* Resolve which Data Machine jobs should be controlled for a job-backed cleanup run.
697+
*
698+
* @param string $operation Cleanup control operation.
699+
* @param int $job_id Cleanup parent job ID.
700+
* @return array<int,int>
701+
*/
702+
private function cleanup_run_control_job_ids( string $operation, int $job_id ): array {
703+
$output = $this->cleanup_run_evidence_store()->read( $this->cleanup_run_id( $job_id ), true, true );
704+
if ( $output instanceof \WP_Error ) {
705+
return array( $job_id );
680706
}
681707

682-
$result['run_id'] = $this->cleanup_run_id( $job_id );
683-
$result['state'] = 'resume' === $operation ? 'running' : 'cancelled';
684-
$this->render_cleanup_control_result( $result, $assoc_args );
708+
$children = (array) ( $output['evidence']['children'] ?? array() );
709+
$processing_ids = array_map( 'intval', (array) ( $children['processing_job_ids'] ?? array() ) );
710+
$failed_ids = array_map( 'intval', (array) ( $children['failed_job_ids'] ?? array() ) );
711+
$pending_ids = array_map( 'intval', (array) ( $children['pending_job_ids'] ?? array() ) );
712+
713+
if ( 'resume' === $operation ) {
714+
$child_targets = array_values( array_unique( array_filter( array_merge( $processing_ids, $failed_ids ) ) ) );
715+
return array() !== $child_targets ? $child_targets : array( $job_id );
716+
}
717+
718+
return array_values( array_unique( array_filter( array_merge( array( $job_id ), $pending_ids, $processing_ids ) ) ) );
685719
}
686720

687721
private function render_cleanup_control_result( array $result, array $assoc_args ): void {

tests/smoke-worktree-cleanup-cli.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,9 +553,11 @@ public function execute( array $input ): array {
553553

554554
class FakeRetryJobAbility {
555555
public array $last_input = array();
556+
public array $inputs = array();
556557

557558
public function execute( array $input ): array {
558559
$this->last_input = $input;
560+
$this->inputs[] = $input;
559561
return array(
560562
'success' => true,
561563
'job_id' => (int) $input['job_id'],
@@ -567,9 +569,11 @@ public function execute( array $input ): array {
567569

568570
class FakeFailJobAbility {
569571
public array $last_input = array();
572+
public array $inputs = array();
570573

571574
public function execute( array $input ): array {
572575
$this->last_input = $input;
576+
$this->inputs[] = $input;
573577
return array(
574578
'success' => true,
575579
'job_id' => (int) $input['job_id'],
@@ -714,11 +718,16 @@ public function execute( array $input ): array {
714718
WP_CLI::$logs = array();
715719
WP_CLI::$successes = array();
716720
$command->cleanup( array( 'resume', 'cleanup-run-123' ), array( 'force' => true, 'format' => 'json' ) );
721+
$resume_json = json_decode( WP_CLI::$logs[0] ?? '', true );
722+
datamachine_code_cleanup_assert( array( 125, 127 ) === ( $resume_json['controlled_job_ids'] ?? array() ), 'cleanup resume controls active child jobs before the parent' );
717723
datamachine_code_cleanup_assert( true === ( $retry_job_ability->last_input['force'] ?? null ), 'cleanup resume forwards force retry flag' );
724+
datamachine_code_cleanup_assert( array( 125, 127 ) === array_map( fn( $input ) => (int) ( $input['job_id'] ?? 0 ), $retry_job_ability->inputs ), 'cleanup resume retries processing and failed child jobs' );
718725

719726
WP_CLI::$logs = array();
720727
WP_CLI::$successes = array();
721728
$command->cleanup( array( 'cancel', 'cleanup-run-123' ), array( 'format' => 'json' ) );
729+
$cancel_json = json_decode( WP_CLI::$logs[0] ?? '', true );
730+
datamachine_code_cleanup_assert( array( 123, 125 ) === ( $cancel_json['controlled_job_ids'] ?? array() ), 'cleanup cancel controls parent and active child jobs' );
722731
datamachine_code_cleanup_assert( 'cleanup_cancelled' === ( $fail_job_ability->last_input['reason'] ?? '' ), 'cleanup cancel fails job with cleanup cancellation reason' );
723732

724733
echo "\n[0] list stale output exposes disk fields\n";

0 commit comments

Comments
 (0)