Worker : simplification — pagedjs-cli ne stream pas la progression page par page hors TTY
All checks were successful
Deploy / deploy (push) Successful in 16s
All checks were successful
Deploy / deploy (push) Successful in 16s
ora désactive le spinner par-page hors TTY et émet seulement 'Rendering: Page 1' puis directement 'Rendering N pages took…'. Sans indicateur de progression réel possible, on retire le streaming (proc_open) et on revient à exec() simple. Le worker écrit maintenant rendering/done uniquement. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
db74e27c3a
commit
56f5a45b7d
2 changed files with 10 additions and 96 deletions
|
|
@ -85,7 +85,7 @@ class PdfGenerator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function generateFromUrlToFile(string $url, string $pdfFile, array $options = [], ?callable $onProgress = null): void
|
public function generateFromUrlToFile(string $url, string $pdfFile, array $options = []): void
|
||||||
{
|
{
|
||||||
$cmd = 'TMPDIR=' . escapeshellarg($this->config['tmp_dir']) . ' ';
|
$cmd = 'TMPDIR=' . escapeshellarg($this->config['tmp_dir']) . ' ';
|
||||||
$cmd .= escapeshellcmd($this->config['pagedjs_bin']);
|
$cmd .= escapeshellcmd($this->config['pagedjs_bin']);
|
||||||
|
|
@ -98,74 +98,14 @@ class PdfGenerator
|
||||||
$cmd .= ' --timeout ' . ($this->config['pagedjs_timeout'] * 1000);
|
$cmd .= ' --timeout ' . ($this->config['pagedjs_timeout'] * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// proc_open pour streamer stdout/stderr ligne par ligne
|
|
||||||
$descriptors = [
|
|
||||||
0 => ['pipe', 'r'],
|
|
||||||
1 => ['pipe', 'w'],
|
|
||||||
2 => ['pipe', 'w'],
|
|
||||||
];
|
|
||||||
$proc = proc_open($cmd, $descriptors, $pipes);
|
|
||||||
if (!is_resource($proc)) {
|
|
||||||
throw new \Exception('Failed to spawn pagedjs-cli');
|
|
||||||
}
|
|
||||||
fclose($pipes[0]);
|
|
||||||
|
|
||||||
stream_set_blocking($pipes[1], false);
|
|
||||||
stream_set_blocking($pipes[2], false);
|
|
||||||
|
|
||||||
$stderrBuffer = '';
|
|
||||||
$partial = ['', ''];
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while (true) {
|
$output = [];
|
||||||
$status = proc_get_status($proc);
|
$returnCode = 0;
|
||||||
$read = [$pipes[1], $pipes[2]];
|
exec($cmd . ' 2>&1', $output, $returnCode);
|
||||||
$w = null; $e = null;
|
|
||||||
$changed = @stream_select($read, $w, $e, 1);
|
|
||||||
|
|
||||||
if ($changed > 0) {
|
if ($returnCode !== 0) {
|
||||||
foreach ($read as $stream) {
|
$this->log('Paged.js CLI error (job): ' . implode("\n", $output));
|
||||||
$idx = ($stream === $pipes[1]) ? 0 : 1;
|
throw new \Exception('PDF generation failed: ' . implode("\n", $output));
|
||||||
$chunk = fread($stream, 4096);
|
|
||||||
if ($chunk === '' || $chunk === false) continue;
|
|
||||||
if ($idx === 1) $stderrBuffer .= $chunk;
|
|
||||||
$partial[$idx] .= $chunk;
|
|
||||||
// Découpe par ligne (\n ou \r — Ora utilise \r pour les spinners)
|
|
||||||
while (preg_match('/^([^\r\n]*)[\r\n](.*)$/s', $partial[$idx], $m)) {
|
|
||||||
$line = $m[1];
|
|
||||||
$partial[$idx] = $m[2];
|
|
||||||
if ($line !== '' && $onProgress !== null) {
|
|
||||||
$onProgress($line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$status['running']) {
|
|
||||||
// Vider les buffers restants
|
|
||||||
foreach ([$pipes[1], $pipes[2]] as $i => $stream) {
|
|
||||||
$idx = ($stream === $pipes[1]) ? 0 : 1;
|
|
||||||
while (($chunk = fread($stream, 4096)) !== false && $chunk !== '') {
|
|
||||||
if ($idx === 1) $stderrBuffer .= $chunk;
|
|
||||||
$partial[$idx] .= $chunk;
|
|
||||||
}
|
|
||||||
if ($partial[$idx] !== '' && $onProgress !== null) {
|
|
||||||
foreach (preg_split('/[\r\n]+/', $partial[$idx]) as $line) {
|
|
||||||
if ($line !== '') $onProgress($line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose($pipes[1]);
|
|
||||||
fclose($pipes[2]);
|
|
||||||
$exitCode = proc_close($proc);
|
|
||||||
|
|
||||||
if ($exitCode !== 0) {
|
|
||||||
$this->log('Paged.js CLI error (URL streaming): ' . $stderrBuffer);
|
|
||||||
throw new \Exception('PDF generation failed: ' . trim($stderrBuffer));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!file_exists($pdfFile)) {
|
if (!file_exists($pdfFile)) {
|
||||||
|
|
|
||||||
32
worker.php
32
worker.php
|
|
@ -50,42 +50,16 @@ set_time_limit(0); // Le worker tourne en arrière-plan, pas de limite
|
||||||
$generator = new \Web2Print\Services\PdfGenerator($config);
|
$generator = new \Web2Print\Services\PdfGenerator($config);
|
||||||
$pdfPath = $jobs->pdfPath($jobId);
|
$pdfPath = $jobs->pdfPath($jobId);
|
||||||
|
|
||||||
$pageCount = 0;
|
|
||||||
$debugLog = $config['log_file'];
|
|
||||||
$logLine = function (string $msg) use ($debugLog, $jobId) {
|
|
||||||
@file_put_contents($debugLog, '[' . date('Y-m-d H:i:s.u') . '] [job ' . $jobId . '] ' . $msg . "\n", FILE_APPEND);
|
|
||||||
};
|
|
||||||
$logLine('worker start, url=' . ($request['url'] ?? '?'));
|
|
||||||
|
|
||||||
$onProgress = function (string $line) use ($jobs, $jobId, &$pageCount, $logLine) {
|
|
||||||
$logLine('stdout: ' . $line);
|
|
||||||
// pagedjs-cli utilise ora qui peut émettre via \r ; on a déjà découpé.
|
|
||||||
// Lignes typiques : "- Loading: ...", "✔ Loaded", "- Rendering: Page X"
|
|
||||||
if (preg_match('/Rendering:\s*Page\s*(\d+)/i', $line, $m)) {
|
|
||||||
$pageCount = max($pageCount, (int)$m[1]);
|
|
||||||
$jobs->writeStatus($jobId, [
|
|
||||||
'status' => 'rendering',
|
|
||||||
'page' => $pageCount,
|
|
||||||
]);
|
|
||||||
} elseif (stripos($line, 'Loaded') !== false) {
|
|
||||||
$jobs->writeStatus($jobId, ['status' => 'rendering', 'page' => 0]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$jobs->writeStatus($jobId, ['status' => 'rendering', 'page' => 0]);
|
$jobs->writeStatus($jobId, ['status' => 'rendering']);
|
||||||
|
|
||||||
$generator->generateFromUrlToFile(
|
$generator->generateFromUrlToFile(
|
||||||
$request['url'],
|
$request['url'],
|
||||||
$pdfPath,
|
$pdfPath,
|
||||||
$request['options'] ?? [],
|
$request['options'] ?? []
|
||||||
$onProgress
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$jobs->writeStatus($jobId, [
|
$jobs->writeStatus($jobId, ['status' => 'done']);
|
||||||
'status' => 'done',
|
|
||||||
'pages' => $pageCount,
|
|
||||||
]);
|
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
$jobs->writeStatus($jobId, [
|
$jobs->writeStatus($jobId, [
|
||||||
'status' => 'error',
|
'status' => 'error',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue