261 lines
7.6 KiB
PHP
261 lines
7.6 KiB
PHP
<?php
|
|
|
|
namespace App\Services\RegisterCreator;
|
|
|
|
use Illuminate\Support\Facades\Cache;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Auth;
|
|
|
|
class ProgressTracker
|
|
{
|
|
private string $jobId;
|
|
private int $totalSteps;
|
|
private int $currentStep = 0;
|
|
private int $totalRegisters = 0;
|
|
private ?string $lineData = null;
|
|
|
|
public function __construct(string $jobId, int $totalSteps = 100, int $totalRegisters = 0, ?string $lineData = null)
|
|
{
|
|
$this->jobId = $jobId;
|
|
$this->totalSteps = $totalSteps;
|
|
$this->totalRegisters = $totalRegisters;
|
|
$this->lineData = $lineData;
|
|
|
|
// Update queue status to "running" when job starts processing
|
|
$this->updateQueueToRunning();
|
|
}
|
|
|
|
/**
|
|
* Update progress in cache
|
|
*/
|
|
public function update(string $description, ?int $customProgress = null, ?int $customCurrent = null): void
|
|
{
|
|
try {
|
|
$progress = $customProgress ?? $this->calculateProgress();
|
|
|
|
// If customCurrent is provided, use it; otherwise use currentStep
|
|
$current = $customCurrent ?? $this->currentStep;
|
|
|
|
$progressData = [
|
|
'total' => $this->totalSteps,
|
|
'current' => $current,
|
|
'progress' => $progress,
|
|
'description' => $description,
|
|
'line_data' => $this->lineData,
|
|
'updated_at' => now()->toDateTimeString(),
|
|
'status' => 'running'
|
|
];
|
|
|
|
Cache::put("register-creator-progress-{$this->jobId}", $progressData, now()->addHours(24));
|
|
|
|
Log::debug("Progress updated for job {$this->jobId}", [
|
|
'line_data' => $this->lineData,
|
|
'progress' => $progress,
|
|
'current' => $current,
|
|
'total' => $this->totalSteps,
|
|
'description' => $description
|
|
]);
|
|
} catch (\Throwable $th) {
|
|
// Don't let progress tracking failure stop the job
|
|
Log::error("Failed to update progress for job {$this->jobId}", [
|
|
'error' => $th->getMessage()
|
|
]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Increment current step
|
|
*/
|
|
public function increment(string $description): void
|
|
{
|
|
$this->currentStep++;
|
|
$this->update($description);
|
|
}
|
|
|
|
/**
|
|
* Set current step
|
|
*/
|
|
public function setStep(int $step, string $description): void
|
|
{
|
|
$this->currentStep = $step;
|
|
$this->update($description);
|
|
}
|
|
|
|
/**
|
|
* Mark as completed
|
|
*/
|
|
public function complete(string $message = 'Completed'): void
|
|
{
|
|
// Set current to total when completing
|
|
$this->update($message, 100, $this->totalSteps);
|
|
|
|
Log::info("Job {$this->jobId} completed", [
|
|
'line_data' => $this->lineData
|
|
]);
|
|
|
|
// Remove from queue after completion
|
|
$this->removeFromQueue();
|
|
}
|
|
|
|
/**
|
|
* Mark as failed
|
|
*/
|
|
public function fail(string $error): void
|
|
{
|
|
Cache::put("register-creator-progress-{$this->jobId}", [
|
|
'total' => $this->totalSteps,
|
|
'current' => $this->currentStep,
|
|
'progress' => $this->calculateProgress(),
|
|
'description' => "Error: {$error}",
|
|
'line_data' => $this->lineData,
|
|
'status' => 'failed',
|
|
'updated_at' => now()->toDateTimeString()
|
|
], now()->addHours(24));
|
|
|
|
Log::error("Job {$this->jobId} failed", [
|
|
'line_data' => $this->lineData,
|
|
'current' => $this->currentStep,
|
|
'total' => $this->totalSteps,
|
|
'error' => $error
|
|
]);
|
|
|
|
// Remove from queue after failure
|
|
$this->removeFromQueue();
|
|
}
|
|
|
|
/**
|
|
* Calculate progress percentage
|
|
*/
|
|
private function calculateProgress(): int
|
|
{
|
|
if ($this->totalSteps === 0) {
|
|
return 0;
|
|
}
|
|
|
|
return min(100, (int) round(($this->currentStep / $this->totalSteps) * 100));
|
|
}
|
|
|
|
/**
|
|
* Get current progress
|
|
*/
|
|
public function get(): ?array
|
|
{
|
|
return Cache::get("register-creator-progress-{$this->jobId}");
|
|
}
|
|
|
|
/**
|
|
* Clear progress from cache
|
|
*/
|
|
public function clear(): void
|
|
{
|
|
Cache::forget("register-creator-progress-{$this->jobId}");
|
|
}
|
|
|
|
/**
|
|
* Update queue status to running when job starts processing
|
|
* Note: Only updates status fields, preserves user and line_identifier from controller
|
|
*/
|
|
private function updateQueueToRunning(): void
|
|
{
|
|
$queue = Cache::get('register-creator-queue-2', []);
|
|
|
|
if (isset($queue[$this->jobId])) {
|
|
// Update only status-related fields, preserve user and line_identifier from controller
|
|
$queue[$this->jobId]['status'] = 'running';
|
|
$queue[$this->jobId]['started_at'] = now()->toDateTimeString();
|
|
|
|
// Update line_identifier only if we have lineData and it's not already set
|
|
if ($this->lineData && empty($queue[$this->jobId]['line_identifier'])) {
|
|
$queue[$this->jobId]['line_identifier'] = $this->lineData;
|
|
}
|
|
|
|
// Sync total_registers with totalSteps if available
|
|
if ($this->totalSteps > 0) {
|
|
$queue[$this->jobId]['total_registers'] = $this->totalSteps;
|
|
}
|
|
|
|
Cache::put('register-creator-queue-2', $queue, now()->addHours(24));
|
|
|
|
Log::info("Job {$this->jobId} status updated to running", [
|
|
'line_data' => $this->lineData,
|
|
'total_documents' => $this->totalSteps,
|
|
'preserved_user' => isset($queue[$this->jobId]['user']) ? 'yes' : 'no',
|
|
'preserved_line_identifier' => $queue[$this->jobId]['line_identifier'] ?? 'none'
|
|
]);
|
|
} else {
|
|
// Fallback: If queue entry doesn't exist, create it
|
|
// This shouldn't happen in normal flow, but added for safety
|
|
Log::warning("Queue entry not found for job {$this->jobId}, creating new entry");
|
|
|
|
try {
|
|
$user = Auth::user();
|
|
} catch (\Throwable $th) {
|
|
$user = null;
|
|
}
|
|
|
|
$queue[$this->jobId] = [
|
|
'user' => $user,
|
|
'total_registers' => $this->totalSteps > 0 ? $this->totalSteps : $this->totalRegisters,
|
|
'line_identifier' => $this->lineData,
|
|
'started_at' => now()->toDateTimeString(),
|
|
'status' => 'running'
|
|
];
|
|
|
|
Cache::put('register-creator-queue-2', $queue, now()->addHours(24));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove this job from the queue
|
|
*/
|
|
private function removeFromQueue(): void
|
|
{
|
|
$queue = Cache::get('register-creator-queue-2', []);
|
|
|
|
if (isset($queue[$this->jobId])) {
|
|
unset($queue[$this->jobId]);
|
|
Cache::put('register-creator-queue-2', $queue, now()->addHours(24));
|
|
|
|
Log::info("Job {$this->jobId} removed from queue", [
|
|
'line_data' => $this->lineData
|
|
]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get job ID
|
|
*/
|
|
public function getJobId(): string
|
|
{
|
|
return $this->jobId;
|
|
}
|
|
|
|
/**
|
|
* Get total registers count
|
|
*/
|
|
public function getTotalRegisters(): int
|
|
{
|
|
return $this->totalRegisters;
|
|
}
|
|
|
|
/**
|
|
* Get line data
|
|
*/
|
|
public function getLineData(): ?string
|
|
{
|
|
return $this->lineData;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|