CaiWuXiTong/app/Console/Commands/JianSunRefreshActiveSnapshots.php

73 lines
2.7 KiB
PHP

<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use Modules\EcommerceFinance\Services\JianSunConnection;
use Modules\EcommerceFinance\Services\JianSunQueryCache;
use Modules\EcommerceFinance\Services\JianSunSnapshotRefresher;
use Throwable;
class JianSunRefreshActiveSnapshots extends Command
{
protected $signature = 'jiansun:snapshots:refresh {--limit= : 本轮最多刷新的活跃查询数}';
protected $description = '在时间和并发预算内刷新最近使用过的 JianSun 本地快照';
public function handle(JianSunQueryCache $cache, JianSunSnapshotRefresher $refresher): int
{
if (! config('jiansun.enabled')) {
$this->components->info('JianSun 同步未启用,本轮跳过。');
return self::SUCCESS;
}
$configuredLimit = max((int) config('jiansun.snapshots.refresh_limit', 2), 1);
$requestedLimit = (int) ($this->option('limit') ?: $configuredLimit);
$entries = $cache->activeEntries(min(max($requestedLimit, 1), $configuredLimit));
$timeBudget = max((int) config('jiansun.snapshots.refresh_time_budget_seconds', 45), 10);
$startedAt = microtime(true);
if ($entries === []) {
$this->components->info('没有需要刷新的活跃查询。');
return self::SUCCESS;
}
$fresh = 0;
$stale = 0;
foreach ($entries as $entry) {
if ((microtime(true) - $startedAt) >= $timeBudget) {
$this->components->info('本轮刷新已达到时间预算,剩余查询留到下一轮。');
break;
}
try {
$status = $refresher->refresh($entry);
$status === 'fresh' ? $fresh++ : $stale++;
} catch (Throwable $exception) {
// 一次连接失败通常会影响全部数据集;立即停止,避免重复登录上游。
JianSunConnection::reset();
Log::error('JianSun 活跃快照刷新失败,本轮已停止。', [
'scope' => $entry['scope'] ?? 'unknown',
'exception' => $exception::class,
]);
$this->components->error('上游刷新失败,本轮已停止;错误类型:' . $exception::class);
return self::FAILURE;
}
$pauseMs = max((int) config('jiansun.snapshots.refresh_pause_ms', 300), 0);
if ($pauseMs > 0) {
usleep($pauseMs * 1000);
}
}
$this->components->info("快照刷新完成:新鲜 {$fresh},沿用旧快照 {$stale}。");
return self::SUCCESS;
}
}