$id, 'status' => 'queued', 'anche_pdf' => $anchePdf, 'total' => $total, 'processed' => 0, 'falliti' => 0, 'logs' => [], 'error' => null, 'started_at' => null, 'finished_at' => null, ]; $this->put($id, $state); Cache::put(self::CHIAVE_CORRENTE, $id, self::TTL_CORRENTE); return $state; } public function corrente(): ?string { $id = Cache::get(self::CHIAVE_CORRENTE); if (! is_string($id) || $id === '') { return null; } $stato = $this->get($id); if ($stato === null || in_array($stato['status'] ?? '', ['completed', 'failed'], true)) { Cache::forget(self::CHIAVE_CORRENTE); return null; } return $id; } public function get(string $id): ?array { return Cache::get($this->key($id)); } public function put(string $id, array $state): void { Cache::put($this->key($id), $state, $this->ttlSeconds); } public function update(string $id, callable $callback): void { $state = $this->get($id); if (! $state) { return; } $this->put($id, $callback($state) ?? $state); } public function log(string $id, string $message): void { $this->update($id, function (array $state) use ($message) { $state['logs'][] = '[' . now()->format('H:i:s') . '] ' . $message; $state['logs'] = array_slice($state['logs'], -self::MAX_LOG); return $state; }); } public function avanza(string $id, int $processed, int $falliti): void { $this->update($id, function (array $state) use ($processed, $falliti) { $state['processed'] = $processed; $state['falliti'] = $falliti; return $state; }); } public function markRunning(string $id): void { $this->update($id, function (array $state) { $state['status'] = 'running'; $state['started_at'] ??= now()->toDateTimeString(); return $state; }); } public function markCompleted(string $id): void { $this->update($id, function (array $state) { $state['status'] = 'completed'; $state['finished_at'] = now()->toDateTimeString(); return $state; }); $this->liberaCorrente($id); } public function markFailed(string $id, string $error): void { $this->update($id, function (array $state) use ($error) { $state['status'] = 'failed'; $state['error'] = $error; $state['finished_at'] = now()->toDateTimeString(); return $state; }); $this->log($id, 'ERRORE: ' . $error); $this->liberaCorrente($id); } private function liberaCorrente(string $id): void { if (Cache::get(self::CHIAVE_CORRENTE) === $id) { Cache::forget(self::CHIAVE_CORRENTE); } } protected function key(string $id): string { return 'piantine-op:' . $id; } }