146 lines
4.1 KiB
PHP
146 lines
4.1 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire;
|
|
|
|
use App\Models\BackupScheduleRun;
|
|
use App\Models\BulkOperationRun;
|
|
use App\Models\Tenant;
|
|
use Illuminate\Support\Arr;
|
|
use Livewire\Attributes\Computed;
|
|
use Livewire\Component;
|
|
|
|
class BulkOperationProgress extends Component
|
|
{
|
|
public $runs;
|
|
|
|
public int $pollSeconds = 3;
|
|
|
|
public int $recentFinishedSeconds = 12;
|
|
|
|
public function mount()
|
|
{
|
|
$this->pollSeconds = max(1, min(10, (int) config('tenantpilot.bulk_operations.poll_interval_seconds', 3)));
|
|
$this->recentFinishedSeconds = max(3, min(60, (int) config('tenantpilot.bulk_operations.recent_finished_seconds', 12)));
|
|
$this->loadRuns();
|
|
}
|
|
|
|
#[Computed]
|
|
public function activeRuns()
|
|
{
|
|
return $this->runs;
|
|
}
|
|
|
|
public function loadRuns()
|
|
{
|
|
try {
|
|
$tenant = Tenant::current();
|
|
} catch (\RuntimeException $e) {
|
|
$this->runs = collect();
|
|
|
|
return;
|
|
}
|
|
|
|
$recentThreshold = now()->subSeconds($this->recentFinishedSeconds);
|
|
|
|
$this->runs = BulkOperationRun::query()
|
|
->where('tenant_id', $tenant->id)
|
|
->where('user_id', auth()->id())
|
|
->where(function ($query) use ($recentThreshold): void {
|
|
$query->whereIn('status', ['pending', 'running'])
|
|
->orWhere(function ($query) use ($recentThreshold): void {
|
|
$query->whereIn('status', ['completed', 'completed_with_errors', 'failed', 'aborted'])
|
|
->where('updated_at', '>=', $recentThreshold);
|
|
});
|
|
})
|
|
->orderByDesc('created_at')
|
|
->get();
|
|
|
|
$this->reconcileBackupScheduleRuns($tenant->id);
|
|
}
|
|
|
|
private function reconcileBackupScheduleRuns(int $tenantId): void
|
|
{
|
|
$userId = auth()->id();
|
|
|
|
if (! $userId) {
|
|
return;
|
|
}
|
|
|
|
$staleThreshold = now()->subSeconds(60);
|
|
|
|
foreach ($this->runs as $bulkRun) {
|
|
if ($bulkRun->resource !== 'backup_schedule') {
|
|
continue;
|
|
}
|
|
|
|
if (! in_array($bulkRun->status, ['pending', 'running'], true)) {
|
|
continue;
|
|
}
|
|
|
|
if (! $bulkRun->created_at || $bulkRun->created_at->gt($staleThreshold)) {
|
|
continue;
|
|
}
|
|
|
|
$scheduleId = (int) Arr::first($bulkRun->item_ids ?? []);
|
|
|
|
if ($scheduleId <= 0) {
|
|
continue;
|
|
}
|
|
|
|
$scheduleRun = BackupScheduleRun::query()
|
|
->where('tenant_id', $tenantId)
|
|
->where('user_id', $userId)
|
|
->where('backup_schedule_id', $scheduleId)
|
|
->where('created_at', '>=', $bulkRun->created_at)
|
|
->orderByDesc('id')
|
|
->first();
|
|
|
|
if (! $scheduleRun) {
|
|
continue;
|
|
}
|
|
|
|
if ($scheduleRun->finished_at) {
|
|
$processed = 1;
|
|
$succeeded = 0;
|
|
$failed = 0;
|
|
$skipped = 0;
|
|
$status = 'completed';
|
|
|
|
switch ($scheduleRun->status) {
|
|
case BackupScheduleRun::STATUS_SUCCESS:
|
|
$succeeded = 1;
|
|
break;
|
|
|
|
case BackupScheduleRun::STATUS_SKIPPED:
|
|
$skipped = 1;
|
|
break;
|
|
|
|
default:
|
|
$failed = 1;
|
|
$status = 'completed_with_errors';
|
|
break;
|
|
}
|
|
|
|
$bulkRun->forceFill([
|
|
'status' => $status,
|
|
'processed_items' => $processed,
|
|
'succeeded' => $succeeded,
|
|
'failed' => $failed,
|
|
'skipped' => $skipped,
|
|
])->save();
|
|
|
|
continue;
|
|
}
|
|
|
|
if ($scheduleRun->started_at && $bulkRun->status === 'pending') {
|
|
$bulkRun->forceFill(['status' => 'running'])->save();
|
|
}
|
|
}
|
|
}
|
|
|
|
public function render(): \Illuminate\Contracts\View\View
|
|
{
|
|
return view('livewire.bulk-operation-progress');
|
|
}
|
|
}
|