Add sync recovery commands for interrupted syncs
- Add wp mls recovery list to show resumable syncs - Add wp mls recovery auto to auto-resume most recent failed sync - Add wp mls recovery cleanup to mark stale syncs (>1hr) as failed - Track last_next_link during incremental sync pagination - Add get_resumable_syncs(), cleanup_stale_syncs(), auto_resume() methods 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -36,6 +36,7 @@ class MLS_CLI {
|
||||
WP_CLI::add_command('mls sync', array($instance, 'sync'));
|
||||
WP_CLI::add_command('mls stats', array($instance, 'stats'));
|
||||
WP_CLI::add_command('mls cache', array($instance, 'cache'));
|
||||
WP_CLI::add_command('mls recovery', array($instance, 'recovery'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -684,6 +685,144 @@ class MLS_CLI {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage sync recovery and resumption.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <action>
|
||||
* : Action: list, auto, cleanup
|
||||
*
|
||||
* [--verbose]
|
||||
* : Show detailed output during resume
|
||||
*
|
||||
* [--quiet]
|
||||
* : Suppress progress output
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp mls recovery list # Show resumable syncs
|
||||
* wp mls recovery auto # Auto-resume most recent failed sync
|
||||
* wp mls recovery auto --verbose # Auto-resume with detailed output
|
||||
* wp mls recovery cleanup # Mark stale syncs as failed
|
||||
*
|
||||
* @subcommand recovery
|
||||
*/
|
||||
public function recovery($args, $assoc_args) {
|
||||
$action = isset($args[0]) ? $args[0] : 'list';
|
||||
$verbose = isset($assoc_args['verbose']);
|
||||
$quiet = isset($assoc_args['quiet']);
|
||||
|
||||
$sync_engine = $this->plugin->get_sync_engine();
|
||||
|
||||
switch ($action) {
|
||||
case 'list':
|
||||
$resumable = $sync_engine->get_resumable_syncs();
|
||||
|
||||
if (empty($resumable)) {
|
||||
WP_CLI::success('No resumable syncs found.');
|
||||
break;
|
||||
}
|
||||
|
||||
WP_CLI::line('');
|
||||
WP_CLI::line('=== Resumable Syncs ===');
|
||||
WP_CLI::line('');
|
||||
|
||||
foreach ($resumable as $sync) {
|
||||
$status_color = $sync->status === 'failed' ? '%R' : '%Y';
|
||||
WP_CLI::line(sprintf(
|
||||
'ID: %d | Type: %s | Status: %s | Processed: %d',
|
||||
$sync->id,
|
||||
$sync->sync_type,
|
||||
$sync->status,
|
||||
$sync->records_processed
|
||||
));
|
||||
WP_CLI::line(sprintf(
|
||||
' Started: %s | Updated: %s',
|
||||
$sync->started_at,
|
||||
$sync->updated_at
|
||||
));
|
||||
if ($sync->last_error) {
|
||||
WP_CLI::warning(' Error: ' . $sync->last_error);
|
||||
}
|
||||
if ($sync->last_next_link) {
|
||||
WP_CLI::line(' Has resume point: Yes');
|
||||
}
|
||||
WP_CLI::line('');
|
||||
}
|
||||
|
||||
WP_CLI::line('To resume a specific sync: wp mls sync resume --id=<ID>');
|
||||
WP_CLI::line('To auto-resume the most recent: wp mls recovery auto');
|
||||
break;
|
||||
|
||||
case 'auto':
|
||||
WP_CLI::line('Checking for resumable syncs...');
|
||||
|
||||
// Build progress callback
|
||||
$progress_callback = null;
|
||||
if (!$quiet) {
|
||||
$progress_callback = function($event, $data = array()) use ($verbose) {
|
||||
if ($verbose) {
|
||||
$this->output_verbose_event($event, $data);
|
||||
} else {
|
||||
switch ($event) {
|
||||
case 'property_created':
|
||||
echo '.';
|
||||
break;
|
||||
case 'property_updated':
|
||||
echo '#';
|
||||
break;
|
||||
case 'property_deleted':
|
||||
echo 'x';
|
||||
break;
|
||||
case 'media_downloaded':
|
||||
echo 'P';
|
||||
break;
|
||||
case 'media_skipped':
|
||||
echo 'p';
|
||||
break;
|
||||
case 'media_error':
|
||||
echo 'E';
|
||||
break;
|
||||
case 'page_complete':
|
||||
echo '|';
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$result = $sync_engine->auto_resume($progress_callback);
|
||||
|
||||
if ($result === null) {
|
||||
WP_CLI::success('No syncs to resume.');
|
||||
break;
|
||||
}
|
||||
|
||||
if (!$quiet && !$verbose) {
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
$this->output_sync_result($result);
|
||||
break;
|
||||
|
||||
case 'cleanup':
|
||||
WP_CLI::line('Cleaning up stale syncs...');
|
||||
|
||||
$cleaned = $sync_engine->cleanup_stale_syncs();
|
||||
|
||||
if ($cleaned > 0) {
|
||||
WP_CLI::success("Marked {$cleaned} stale sync(s) as failed.");
|
||||
} else {
|
||||
WP_CLI::success('No stale syncs found.');
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
WP_CLI::error("Unknown action: {$action}. Use 'list', 'auto', or 'cleanup'.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively delete a directory
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user