CaiWuXiTong/app/Console/Commands/UpstreamSyncSchemaCatalog.php

90 lines
2.8 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Console\Commands;
use Illuminate\Cache\CacheManager;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Modules\EcommerceFinance\Services\UpstreamSchemaCatalogSynchronizer;
use Modules\EcommerceFinance\Services\UpstreamSourceRegistry;
use Throwable;
class UpstreamSyncSchemaCatalog extends Command
{
protected $signature = 'upstream:schema:sync
{source? : 仅同步指定来源}
{--due : 仅同步超过 24 小时未更新的来源}';
protected $description = '低频同步上游表、视图和字段目录到共享系统数据库';
public function handle(
UpstreamSchemaCatalogSynchronizer $synchronizer,
UpstreamSourceRegistry $sources,
CacheManager $cacheManager,
): int {
if (! $synchronizer->ready()) {
$this->warn('共享系统数据库尚未执行数据字典迁移。');
return self::SUCCESS;
}
$requested = $this->argument('source');
$sourceKeys = $requested
? [(string) $requested]
: array_keys($sources->all());
$cache = $cacheManager->store((string) config('upstreams.snapshots.cache_store', 'upstream_shared'));
$failed = false;
foreach ($sourceKeys as $source) {
try {
$sources->definition($source);
if (! $sources->enabled($source) || $this->isFresh($source)) {
continue;
}
$lock = $cache->lock('upstream:schema-sync:' . $source, 600);
if (! $lock->get()) {
continue;
}
try {
$result = $synchronizer->sync($source);
$this->info(sprintf(
'%s:已同步 %d 个对象、%d 个字段。',
$source,
$result['objects'],
$result['columns']
));
} finally {
$lock->release();
}
} catch (Throwable $exception) {
$failed = true;
Log::warning('上游数据字典同步失败,已保留原目录。', [
'source' => $source,
'exception' => $exception::class,
]);
$this->error($source . ':同步失败,已保留原目录。');
}
}
return $failed ? self::FAILURE : self::SUCCESS;
}
private function isFresh(string $source): bool
{
if (! $this->option('due')) {
return false;
}
$latest = DB::table('upstream_schema_columns')
->where('source_key', $source)
->max('synchronized_at');
return $latest !== null && now()->diffInHours($latest) < 24;
}
}