Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
@@ -1,22 +1,38 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Framework\Queue;
|
||||
|
||||
use App\Framework\Cache\Serializer;
|
||||
use App\Framework\Cache\Serializer\PhpSerializer;
|
||||
use App\Framework\Logging\DefaultLogger;
|
||||
use App\Framework\Logging\Logger;
|
||||
use App\Framework\Logging\LogLevel;
|
||||
use App\Framework\Logging\ProcessorManager;
|
||||
use App\Framework\Serializer\Php\PhpSerializer;
|
||||
use App\Framework\Serializer\Serializer;
|
||||
|
||||
final readonly class FileQueue implements Queue
|
||||
{
|
||||
private string $queueDir;
|
||||
|
||||
private Logger $logger;
|
||||
|
||||
public function __construct(
|
||||
string $queueDir,
|
||||
private Serializer $serializer = new PhpSerializer())
|
||||
{
|
||||
private Serializer $serializer = new PhpSerializer(),
|
||||
?Logger $logger = null
|
||||
) {
|
||||
$this->queueDir = $queueDir;
|
||||
if (!is_dir($queueDir)) {
|
||||
if (! is_dir($queueDir)) {
|
||||
mkdir($queueDir, 0777, true);
|
||||
}
|
||||
|
||||
// Use provided logger or create a null logger for production
|
||||
$this->logger = $logger ?? new DefaultLogger(
|
||||
minLevel: LogLevel::WARNING,
|
||||
handlers: [],
|
||||
processorManager: new ProcessorManager()
|
||||
);
|
||||
}
|
||||
|
||||
public function push(object $job): void
|
||||
@@ -25,46 +41,32 @@ final readonly class FileQueue implements Queue
|
||||
$jobHash = md5($this->serializer->serialize($job));
|
||||
$hashFile = $this->queueDir . '/hash_' . $jobHash . '.job';
|
||||
|
||||
// DETAILED DEBUG: Wer ruft push() auf?
|
||||
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10);
|
||||
$caller = '';
|
||||
foreach ($trace as $frame) {
|
||||
if (isset($frame['file']) && isset($frame['line'])) {
|
||||
$caller .= basename($frame['file']) . ':' . $frame['line'] . ' -> ';
|
||||
}
|
||||
}
|
||||
|
||||
error_log("FileQueue Debug: PUSH called from: " . $caller);
|
||||
error_log("FileQueue Debug: Job class: " . get_class($job));
|
||||
error_log("FileQueue Debug: Job data: " . json_encode($job));
|
||||
error_log("FileQueue Debug: Job hash: " . $jobHash);
|
||||
// Debug logging removed for production
|
||||
|
||||
// Prüfe ob identischer Job bereits existiert
|
||||
if (file_exists($hashFile)) {
|
||||
error_log("FileQueue Debug: ⚠️ DUPLICATE JOB REJECTED - hash already exists: " . $jobHash);
|
||||
error_log("FileQueue Debug: Called from: " . $caller);
|
||||
// Silent deduplication - no logging needed in production
|
||||
return; // Job wird nicht hinzugefügt
|
||||
}
|
||||
|
||||
// Verwende Hash als Dateiname für automatische Deduplication
|
||||
file_put_contents($hashFile, $this->serializer->serialize($job));
|
||||
error_log("FileQueue Debug: ✅ Job added with hash: " . $jobHash);
|
||||
// No logging for successful job addition in production
|
||||
}
|
||||
|
||||
public function pop(): ?object
|
||||
{
|
||||
$files = glob($this->queueDir . '/*.job');
|
||||
|
||||
// Debug: Queue-Status loggen
|
||||
// Queue-Status - no logging in production
|
||||
if (empty($files)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
error_log("FileQueue Debug: Found " . count($files) . " job files in " . $this->queueDir);
|
||||
error_log("FileQueue Debug: Files: " . implode(', ', array_map('basename', $files)));
|
||||
// No debug logging for job discovery in production
|
||||
|
||||
// Sortiere nach Erstellungsdatum (FIFO)
|
||||
usort($files, function($a, $b) {
|
||||
usort($files, function ($a, $b) {
|
||||
return filemtime($a) <=> filemtime($b);
|
||||
});
|
||||
|
||||
@@ -73,29 +75,32 @@ final readonly class FileQueue implements Queue
|
||||
|
||||
// Atomic Lock-Mechanismus um race conditions zu verhindern
|
||||
if (file_exists($lockFile)) {
|
||||
error_log("FileQueue Debug: Job file is locked: $file");
|
||||
// Silent handling of locked files - normal operation
|
||||
return null; // Job wird bereits verarbeitet
|
||||
}
|
||||
|
||||
// Lock erstellen
|
||||
if (!@touch($lockFile)) {
|
||||
error_log("FileQueue Debug: Could not create lock file: $lockFile");
|
||||
if (! @touch($lockFile)) {
|
||||
$this->logger->warning("FileQueue: ⚠️ Could not create lock file", ['lock_file' => basename($lockFile)]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
// Prüfe ob Datei noch existiert (race condition)
|
||||
if (!file_exists($file) || !is_readable($file)) {
|
||||
error_log("FileQueue Debug: Job file not accessible: $file");
|
||||
if (! file_exists($file) || ! is_readable($file)) {
|
||||
$this->logger->warning("FileQueue: ⚠️ Job file not accessible", ['file' => basename($file)]);
|
||||
@unlink($lockFile);
|
||||
|
||||
return $this->pop();
|
||||
}
|
||||
|
||||
$content = file_get_contents($file);
|
||||
if ($content === false) {
|
||||
error_log("FileQueue Debug: Could not read job file: $file");
|
||||
$this->logger->error("FileQueue: ❌ Could not read job file", ['file' => basename($file)]);
|
||||
@unlink($file);
|
||||
@unlink($lockFile);
|
||||
|
||||
return $this->pop();
|
||||
}
|
||||
|
||||
@@ -105,24 +110,29 @@ final readonly class FileQueue implements Queue
|
||||
$tempFile = $file . '.deleting.' . time() . '.' . getmypid();
|
||||
if (rename($file, $tempFile)) {
|
||||
unlink($tempFile);
|
||||
error_log("FileQueue Debug: Successfully deleted job file: " . basename($file));
|
||||
// No logging for successful job completion in production
|
||||
} else {
|
||||
error_log("FileQueue Debug: Failed to rename job file for deletion: $file");
|
||||
$this->logger->warning("FileQueue: ⚠️ Failed to rename job file for deletion", ['file' => basename($file)]);
|
||||
// Fallback: direktes löschen versuchen
|
||||
if (!@unlink($file)) {
|
||||
error_log("FileQueue Debug: Failed to delete job file: $file - moving to processed");
|
||||
if (! @unlink($file)) {
|
||||
$this->logger->warning("FileQueue: ⚠️ Failed to delete job file - moving to processed", ['file' => basename($file)]);
|
||||
$processedFile = $file . '.processed.' . time();
|
||||
@rename($file, $processedFile);
|
||||
}
|
||||
}
|
||||
|
||||
@unlink($lockFile);
|
||||
|
||||
return $job;
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
error_log("FileQueue Debug: Failed to process job from file $file: " . $e->getMessage());
|
||||
$this->logger->error("FileQueue: ❌ Failed to process job", [
|
||||
'file' => basename($file),
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
@unlink($file);
|
||||
@unlink($lockFile);
|
||||
|
||||
return $this->pop();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user