Skip to content

Commit 2cac59a

Browse files
authored
Merge pull request #680 from Extra-Chill/fix/issue-677-cleanup-parent-convergence
Fix cleanup parent status convergence
2 parents bca4a85 + 5aaeac9 commit 2cac59a

2 files changed

Lines changed: 208 additions & 81 deletions

File tree

inc/Cleanup/DataMachineJobCleanupRunEvidenceStore.php

Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,17 @@ public function read( string $run_id, bool $include_evidence = false, bool $incl
3737
$child_jobs = $this->get_cleanup_run_descendant_jobs($job_id);
3838
$aggregate = $this->aggregate_cleanup_child_jobs($child_jobs);
3939
$children = $aggregate['children'];
40-
$state = $this->cleanup_run_state( (string) ( $job['status'] ?? '' ), $children);
40+
$parent_status = (string) ( $job['status'] ?? '' );
41+
$state = $this->cleanup_run_state($parent_status, $children, $parent_result, $aggregate);
4142

4243
$children_for_output = ( $include_evidence || $include_details ) ? $children : $this->summarize_cleanup_children($children);
4344
$output = array(
4445
'success' => true,
4546
'state' => $state,
4647
'run_id' => $this->cleanup_run_id($job_id),
4748
'job_id' => $job_id,
48-
'status' => in_array($state, array( 'children_processing', 'partial_failed' ), true) ? $state : ( $job['status'] ?? '' ),
49+
'status' => $state,
50+
'parent_status' => $parent_status,
4951
'created_at' => $job['created_at'] ?? '',
5052
'parent_completed_at' => $job['completed_at'] ?? '',
5153
'artifact_cleanup' => $aggregate['artifact_cleanup'],
@@ -132,6 +134,7 @@ private function aggregate_cleanup_child_jobs( array $child_jobs ): array {
132134
'processing' => 0,
133135
'completed' => 0,
134136
'failed' => 0,
137+
'skipped' => 0,
135138
'running' => 0,
136139
'total' => 0,
137140
'statuses' => array(),
@@ -218,6 +221,7 @@ private function summarize_cleanup_children( array $children ): array {
218221
'processing' => (int) ( $children['processing'] ?? 0 ),
219222
'completed' => (int) ( $children['completed'] ?? 0 ),
220223
'failed' => (int) ( $children['failed'] ?? 0 ),
224+
'skipped' => (int) ( $children['skipped'] ?? 0 ),
221225
'running' => (int) ( $children['running'] ?? 0 ),
222226
'total' => (int) ( $children['total'] ?? 0 ),
223227
'statuses' => (array) ( $children['statuses'] ?? array() ),
@@ -255,9 +259,9 @@ private function cleanup_run_drain_summary( int $job_id, string $state, array $c
255259
)
256260
)
257261
);
258-
$run_id = $this->cleanup_run_id($job_id);
259-
$cleanup_items = (array) ( $aggregate['cleanup_items'] ?? array() );
260-
$commands = array(
262+
$run_id = $this->cleanup_run_id($job_id);
263+
$cleanup_items = (array) ( $aggregate['cleanup_items'] ?? array() );
264+
$commands = array(
261265
'parent' => sprintf('studio wp datamachine drain --job-id=%d', $job_id),
262266
'verify' => sprintf('studio wp datamachine-code workspace cleanup status %s --format=json', $run_id),
263267
);
@@ -266,7 +270,7 @@ private function cleanup_run_drain_summary( int $job_id, string $state, array $c
266270
}
267271

268272
return array(
269-
'needed' => in_array($state, array( 'running', 'children_processing' ), true),
273+
'needed' => in_array($state, array( 'running', 'waiting_on_children' ), true),
270274
'commands' => $commands,
271275
'active_child_job_ids' => $active_child_ids,
272276
'bytes_reclaimed' => (int) ( $cleanup_items['bytes_reclaimed'] ?? 0 ),
@@ -478,6 +482,10 @@ private function count_cleanup_child_status( array &$children, string $status ):
478482
++$children['failed'];
479483
return;
480484
}
485+
if ( str_starts_with($status, 'skipped') ) {
486+
++$children['skipped'];
487+
return;
488+
}
481489
if ( str_starts_with($status, 'completed') ) {
482490
++$children['completed'];
483491
}
@@ -546,9 +554,6 @@ private function merge_cleanup_reason_examples( array &$examples, array $rows ):
546554
private function sum_cleanup_rows_bytes( array $rows, array $fields ): int {
547555
$total = 0;
548556
foreach ( $rows as $row ) {
549-
if ( ! is_array($row) ) {
550-
continue;
551-
}
552557
$found = false;
553558
foreach ( $fields as $field ) {
554559
if ( isset($row[ $field ]) ) {
@@ -574,22 +579,69 @@ private function sum_cleanup_rows_bytes( array $rows, array $fields ): int {
574579
* @param array $children Child summary.
575580
* @return string
576581
*/
577-
private function cleanup_run_state( string $status, array $children ): string {
582+
private function cleanup_run_state( string $status, array $children, array $parent_result, array $aggregate ): string {
578583
$parent_state = $this->cleanup_job_state($status);
579-
if ( in_array($parent_state, array( 'cancelled', 'partial_failure' ), true) ) {
584+
if ( in_array($parent_state, array( 'cancelled', 'failed' ), true) ) {
580585
return $parent_state;
581586
}
582587

583588
if ( (int) ( $children['running'] ?? 0 ) > 0 ) {
584-
return 'children_processing';
589+
return 'waiting_on_children';
585590
}
586591
if ( (int) ( $children['failed'] ?? 0 ) > 0 ) {
587-
return 'partial_failed';
592+
return 'failed';
593+
}
594+
595+
$child_total = (int) ( $children['total'] ?? 0 );
596+
$terminal_child = (int) ( $children['completed'] ?? 0 ) + (int) ( $children['skipped'] ?? 0 );
597+
if ( $child_total > 0 && $terminal_child >= $child_total ) {
598+
return 'complete';
599+
}
600+
601+
if ( 0 === $child_total && $this->cleanup_parent_has_no_planned_work($parent_result, $aggregate) ) {
602+
return 'no_work';
588603
}
589604

590605
return $parent_state;
591606
}
592607

608+
/**
609+
* Determine whether parent cleanup evidence proves there was no work to schedule.
610+
*
611+
* @param array $parent_result Parent system task result.
612+
* @param array $aggregate Child aggregate.
613+
* @return bool
614+
*/
615+
private function cleanup_parent_has_no_planned_work( array $parent_result, array $aggregate ): bool {
616+
if ( array() === $parent_result ) {
617+
return false;
618+
}
619+
620+
$cleanup_items = (array) ( $aggregate['cleanup_items'] ?? array() );
621+
if ( (int) ( $cleanup_items['planned_rows'] ?? 0 ) > 0 ) {
622+
return false;
623+
}
624+
625+
if ( array_key_exists('chunks', $parent_result) && array() !== (array) $parent_result['chunks'] ) {
626+
return false;
627+
}
628+
629+
if ( isset($parent_result['evidence']) && is_array($parent_result['evidence']) && (int) ( $parent_result['evidence']['planned_chunks'] ?? 0 ) > 0 ) {
630+
return false;
631+
}
632+
633+
if ( isset($parent_result['chunk_row_counts']) && is_array($parent_result['chunk_row_counts']) ) {
634+
foreach ( $parent_result['chunk_row_counts'] as $count ) {
635+
if ( (int) $count > 0 ) {
636+
return false;
637+
}
638+
}
639+
return true;
640+
}
641+
642+
return array_key_exists('chunks', $parent_result) || array_key_exists('chunk_row_counts', $parent_result);
643+
}
644+
593645
/**
594646
* Convert job status into cleanup run state.
595647
*
@@ -604,7 +656,7 @@ private function cleanup_job_state( string $status ): string {
604656
return 'cancelled';
605657
}
606658
if ( str_starts_with($status, 'failed') ) {
607-
return 'partial_failure';
659+
return 'failed';
608660
}
609661
if ( str_starts_with($status, 'completed') ) {
610662
return 'complete';

0 commit comments

Comments
 (0)