Skip to content

Commit fdf9c34

Browse files
Fix active no-signal drain restart continuation (#850)
* Fix active no-signal drain restart continuation * Satisfy active no-signal cleanup lint --------- Co-authored-by: homeboy-ci[bot] <266378653+homeboy-ci[bot]@users.noreply.github.com>
1 parent dd9eba5 commit fdf9c34

2 files changed

Lines changed: 28 additions & 22 deletions

File tree

inc/Workspace/WorkspaceAbandonedCleanupOrchestrator.php

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -377,9 +377,9 @@ private function append_active_no_signal_backlog_summary( array &$result, int $l
377377
);
378378
if ( is_wp_error($report) ) {
379379
$result['remaining_active_no_signal_backlog'] = array(
380-
'available' => false,
381-
'reason' => (string) $report->get_error_code(),
382-
'message' => $report->get_error_message(),
380+
'available' => false,
381+
'reason' => (string) $report->get_error_code(),
382+
'message' => $report->get_error_message(),
383383
'next_commands' => array(
384384
sprintf('studio wp datamachine-code workspace worktree active-no-signal-report --limit=%d --offset=0 --format=json', $limit),
385385
),
@@ -414,7 +414,7 @@ private function build_active_no_signal_backlog_summary( array $report, int $lim
414414
if ( ! is_array($row) ) {
415415
continue;
416416
}
417-
$reason = (string) ( $row['suggested_action'] ?? 'insufficient_signal' );
417+
$reason = (string) ( $row['suggested_action'] ?? 'insufficient_signal' );
418418
$buckets[ $reason ] ??= array(
419419
'count' => 0,
420420
'examples' => array(),
@@ -437,15 +437,15 @@ private function build_active_no_signal_backlog_summary( array $report, int $lim
437437
}
438438

439439
return array(
440-
'available' => true,
441-
'total_active_no_signal' => $total,
442-
'sampled' => $sampled,
443-
'unreviewed_count' => max(0, $total - $sampled),
444-
'by_actionable_reason' => $buckets,
445-
'counts_scope' => 'bounded_post_drain_sample_only',
446-
'limitation' => 'Counts by actionable reason cover only this bounded post-drain sample; active-no-signal report has pagination but no safe bucket filter, so full per-bucket totals are not scanned by default.',
447-
'pagination' => $pagination,
448-
'next_commands' => array_values(array_unique(array_filter($commands))),
440+
'available' => true,
441+
'total_active_no_signal' => $total,
442+
'sampled' => $sampled,
443+
'unreviewed_count' => max(0, $total - $sampled),
444+
'by_actionable_reason' => $buckets,
445+
'counts_scope' => 'bounded_post_drain_sample_only',
446+
'limitation' => 'Counts by actionable reason cover only this bounded post-drain sample; active-no-signal report has pagination but no safe bucket filter, so full per-bucket totals are not scanned by default.',
447+
'pagination' => $pagination,
448+
'next_commands' => array_values(array_unique($commands)),
449449
);
450450
}
451451

@@ -517,16 +517,17 @@ private function run_bounded_apply( object $ability, array &$result, bool $apply
517517
}
518518

519519
private function build_continuation( string $stage, array $step, int $limit, int $passes, bool $force, string $until_budget, bool $active_no_signal_drain = false ): array {
520-
$pagination = (array) ( $step['pagination'] ?? $step['continuation'] ?? array() );
521-
$next_offset = isset($pagination['next_offset']) ? max(0, (int) $pagination['next_offset']) : 0;
522-
$command = $this->build_continuation_command($stage, $next_offset, $limit, $passes, $force, $until_budget, $active_no_signal_drain);
523-
$current = (int) ( $pagination['offset'] ?? 0 );
524-
$mutated = (int) ( $step['summary']['written'] ?? 0 ) + (int) ( $step['summary']['removed'] ?? 0 );
525-
$restart = ! empty($pagination['partial']) && $next_offset <= $current && $mutated > 0;
520+
$pagination = (array) ( $step['pagination'] ?? $step['continuation'] ?? array() );
521+
$next_offset = isset($pagination['next_offset']) ? max(0, (int) $pagination['next_offset']) : 0;
522+
$current = (int) ( $pagination['offset'] ?? 0 );
523+
$mutated = (int) ( $step['summary']['written'] ?? 0 ) + (int) ( $step['summary']['removed'] ?? 0 );
524+
$restart = ! empty($pagination['partial']) && $next_offset <= $current && $mutated > 0;
525+
$command_offset = $restart ? 0 : $next_offset;
526+
$command = $this->build_continuation_command($stage, $command_offset, $limit, $passes, $force, $until_budget, $active_no_signal_drain);
526527

527528
$continuation = array(
528529
'stage' => $stage,
529-
'offset' => $next_offset,
530+
'offset' => $command_offset,
530531
'next_command' => $command,
531532
'pagination' => $pagination,
532533
);
@@ -542,7 +543,8 @@ private function build_continuation( string $stage, array $step, int $limit, int
542543
'removed' => $removed,
543544
'total_mutations' => $written + $removed,
544545
'previous_offset' => $current,
545-
'restart_offset' => $next_offset,
546+
'next_offset' => $next_offset,
547+
'restart_offset' => 0,
546548
'candidate_set_now' => 'changed',
547549
);
548550
$continuation['next_command_label'] = 'Restart this stage from offset 0 because the cleanup candidate set changed.';

tests/smoke-abandoned-cleanup-orchestrator.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ function abandoned_cleanup_assert( bool $condition, string $label ): void {
236236
$candidate_set_changed = new AbandonedCleanupFakeAbility(
237237
'finalized',
238238
array( 'inspected' => 1, 'written' => 1 ),
239-
array( 'offset' => 0, 'limit' => 10, 'scanned' => 1, 'partial' => true, 'complete' => false, 'next_offset' => 0 )
239+
array( 'offset' => 10, 'limit' => 10, 'scanned' => 1, 'partial' => true, 'complete' => false, 'next_offset' => 10 )
240240
);
241241
$restart_abilities = array(
242242
'datamachine-code/workspace-worktree-reconcile-metadata' => new AbandonedCleanupFakeAbility('reconcile_metadata', array(), array( 'complete' => true )),
@@ -265,9 +265,13 @@ static function () use ( &$clock_index, $clock_values ): float {
265265
abandoned_cleanup_assert(str_contains((string) $restart_result['continuation']['reason_description'], 'candidate set'), 'restart continuation explains why offset zero is expected');
266266
abandoned_cleanup_assert(1 === (int) $restart_result['continuation']['progress_delta']['written'], 'restart continuation exposes written progress delta');
267267
abandoned_cleanup_assert(1 === (int) $restart_result['continuation']['progress_delta']['total_mutations'], 'restart continuation exposes total mutation progress delta');
268+
abandoned_cleanup_assert(10 === (int) $restart_result['continuation']['progress_delta']['previous_offset'], 'restart continuation documents the previous offset');
269+
abandoned_cleanup_assert(10 === (int) $restart_result['continuation']['progress_delta']['next_offset'], 'restart continuation documents the unsafe candidate-set continuation offset');
268270
abandoned_cleanup_assert(0 === (int) $restart_result['continuation']['progress_delta']['restart_offset'], 'restart continuation exposes the intentional restart offset');
271+
abandoned_cleanup_assert(0 === (int) $restart_result['continuation']['offset'], 'restart continuation top-level offset matches the restart command offset');
269272
abandoned_cleanup_assert(str_contains((string) $restart_result['continuation']['next_command_label'], 'candidate set changed'), 'restart continuation labels the restart command');
270273
abandoned_cleanup_assert('active-no-signal-drain' === explode(' ', (string) $restart_result['continuation']['next_command'])[5], 'restart next command uses active/no-signal drain');
274+
abandoned_cleanup_assert(str_contains((string) $restart_result['continuation']['next_command'], '--offset=0'), 'restart next command restarts active/no-signal drain at offset zero');
271275

272276
$stage_budget_abilities = array(
273277
'datamachine-code/workspace-worktree-reconcile-metadata' => new AbandonedCleanupFakeAbility('reconcile_metadata', array(), array( 'complete' => true )),

0 commit comments

Comments
 (0)