Contrats / Observabilité
Le domaine d’observabilité regroupe les contrats qui exposent l’état d’exécution du moteur : ContextAwareExceptionInterface pour un contexte d’erreur structuré, SpectrumInterface pour le sidecar d’accélération optionnel, JobNotificationInterface pour le suivi en flux de la progression des jobs, et l’énumération DegradationPolicy pour le comportement à adopter en cas de perte de capacité.
Installation
Section intitulée « Installation »composer require nextpdf/core:^3Vue d’ensemble conceptuelle
Section intitulée « Vue d’ensemble conceptuelle »ContextAwareExceptionInterface est le contrat de diagnostic. Chaque exception de domaine NextPDF l’implémente. Toute exception NextPDF capturée peut être convertie vers ce type pour récupérer un contexte structuré destiné à un outil de surveillance des performances applicatives (APM), à un pipeline de journalisation ou à un rapporteur d’erreurs. Le contexte est un tableau associatif dont les clés sont en snake_case et dont les valeurs sont exclusivement primitives. Il ne contient aucun objet imbriqué et se sérialise donc sans surprise en charge utile JSON ou APM. Tu n’as plus besoin d’analyser le message d’exception pour extraire les données de diagnostic. Il est stable depuis la version 3.1.0.
SpectrumInterface est le contrat du sidecar d’accélération optionnel. Spectrum est un moteur parallèle sur CPU qui délègue la détection du matériel, l’analyse des PDF et la compression des images à un processus sidecar local. Le contrat signale la disponibilité via un disjoncteur (circuit breaker), afin qu’un contrôle de santé fréquent ne propage pas de défaillance en cascade lorsque le sidecar est hors service. Il sonde les capacités matérielles avec un résultat mis en cache. Il expose le budget de ressources actif. Il fournit un transport de requêtes générique pour les modules de plus haut niveau. Le moteur fonctionne sans le sidecar. Le contrat existe pour que l’accélération reste une option injectable, et non une dépendance obligatoire. JobNotificationInterface diffuse des événements de job typés depuis le point de terminaison server-sent-events du sidecar sous forme de générateur. Le générateur se termine lorsqu’un événement terminal arrive ou lorsque le flux se ferme.
DegradationPolicy est l’énumération qui décrit le comportement en cas de perte de capacité. Quand une capacité se dégrade, la politique décide de lever une exception, d’émettre un avertissement ou de collecter l’événement en silence, en tenant compte de l’impact. Strict lève une exception quand l’impact correspond à un risque de conformité, à une perte sémantique ou à un blocage. C’est le choix adapté à un environnement réglementé où la justesse de la sortie est obligatoire. Balanced, la valeur par défaut, émet des avertissements structurés et continue en cas de dégradation bornée, et ne lève une exception que pour un impact bloquant. C’est le choix adapté à la plupart des déploiements en production. Permissive collecte chaque événement en silence et ne lève jamais d’exception. C’est le choix adapté à un mode prévisualisation ou brouillon où une sortie produite au mieux est acceptable. Les types SpectrumInterface, JobNotificationInterface et DegradationPolicy sont experimental. Leur promesse de compatibilité est moins forte que celle de ContextAwareExceptionInterface.
Surface d’API
Section intitulée « Surface d’API »| Type | Genre | Membres clés | Stabilité | Depuis |
|---|---|---|---|---|
ContextAwareExceptionInterface | interface | getContext(): array<string, mixed> | stable | 3.1.0 |
SpectrumInterface | interface | isAvailable(), probe(), getBudget(), request() | experimental | 2.1.0 |
JobNotificationInterface | interface | streamEvents(string): Generator<int, JobEvent> | experimental | 2.2.0 |
DegradationPolicy | énumération (chaîne) | Strict, Balanced, Permissive | experimental | 2.3.0 |
getContext() renvoie uniquement des primitives ou des listes de primitives. streamEvents() produit des objets JobEvent jusqu’à rencontrer un événement terminal. SpectrumInterface::request() renvoie le corps de réponse brut sous forme de string. probe() renvoie un HardwareReport, et getBudget() renvoie un SpectrumBudget.
Exemple de code — Démarrage rapide
Section intitulée « Exemple de code — Démarrage rapide »<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\ContextAwareExceptionInterface;use Psr\Log\LoggerInterface;
/** * Log a NextPDF exception with its structured context. * * @param \Throwable $e A caught exception. * @param LoggerInterface $logger A PSR-3 logger. */function logWithContext(\Throwable $e, LoggerInterface $logger): void{ if ($e instanceof ContextAwareExceptionInterface) { $logger->error($e->getMessage(), $e->getContext());
return; }
$logger->error($e->getMessage());}Le contexte structuré est transmis à l’enregistrement de journal sans analyse du message.
Exemple de code — Production
Section intitulée « Exemple de code — Production »<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\DegradationPolicy;use NextPDF\Contracts\SpectrumInterface;use Psr\Log\LoggerInterface;
final readonly class AcceleratedParseService{ public function __construct( private ?SpectrumInterface $spectrum, private DegradationPolicy $policy, private LoggerInterface $logger, ) {}
/** * Send a parse batch to the sidecar when healthy, otherwise fall back. * * @param list<array{id: string, data: string}> $documents PDF binaries with caller IDs. * * @return string Raw sidecar response body; decode with a batch-result parser. */ public function parse(array $documents): string { if ($this->spectrum?->isAvailable() === true) { return $this->spectrum->request( 'POST', '/v1/parse', json: ['documents' => $documents], scope: ['parse'], ); }
if ($this->policy === DegradationPolicy::Strict) { throw new \RuntimeException('Accelerator required under strict policy.'); }
$this->logger->info('Accelerator unavailable; using PHP fallback.');
return $this->phpFallback($documents); }
/** @param list<array{id: string, data: string}> $documents @return string */ private function phpFallback(array $documents): string { // Pure-PHP parse path omitted for brevity. return ''; }}Une dépendance SpectrumInterface nullable rend l’accélération optionnelle. Le contrat expose une seule méthode de transport, request(), qui renvoie le corps de réponse brut sous forme de string. Un analyseur de plus haut niveau transforme ce corps en NextPDF\Accelerator\BatchResult. Le SpectrumClient concret ajoute des assistants typés comme parseBatch(), qui enveloppent request() et renvoient directement un BatchResult. Ces assistants ne font pas partie du contrat figé. La politique de dégradation détermine si l’absence du sidecar est fatale.
Cas limites & pièges
Section intitulée « Cas limites & pièges »- Tout
\Throwablen’est pas nécessairement une exception NextPDF. Protège toujours l’appel avecinstanceof ContextAwareExceptionInterfaceavant d’appelergetContext(). getContext()renvoie uniquement des primitives, par contrat. Un consommateur qui s’attend à des objets imbriqués part d’une hypothèse fausse ; le contrat garantit des valeurs compatibles JSON.SpectrumInterface::isAvailable()est protégé par un disjoncteur et peut être appelé souvent sans risque, mais un résultattruereste un contrôle à un instant donné. Gère le cas où le sidecar disparaît entre le contrôle et l’appel.JobNotificationInterface::streamEvents()est un générateur. L’itérer deux fois ne rejoue pas les événements. Consomme-le une seule fois.DegradationPolicy::Permissivene lève jamais d’exception. Dans ce mode, une dégradation qui affecte la conformité passe en silence. Ne l’utilise pas pour une sortie réglementée.
Performances
Section intitulée « Performances »Les contrats d’observabilité ajoutent un coût négligeable. getContext() renvoie un tableau préconstruit. isAvailable() est une sonde de santé mise en cache et protégée par un disjoncteur. Le contrat exige que les implémentations mettent en cache le résultat de la sonde pendant au moins 30 secondes, afin qu’un chemin critique n’appelle pas le sidecar de manière répétée. streamEvents() est limité par le débit d’événements du sidecar, pas par le moteur. Le performance_budget de 1500 ms d’horloge murale et 64 Mo de pic est fixé par le travail sous-jacent que les contrats observent, pas par les contrats eux-mêmes. Le profil de reproductibilité est structural. Un flux d’événements et un contexte d’exception incluent des horodatages. Deux exécutions diffèrent sur ces champs, tandis que la structure reste identique.
Notes de sécurité
Section intitulée « Notes de sécurité »Le contexte d’exception structuré devient un vecteur d’exfiltration de données s’il transporte des secrets. Le contrat restreint le contexte aux primitives, ce qui limite la fuite accidentelle d’objets. Un déploiement doit tout de même nettoyer les valeurs sensibles avant que le contexte n’atteigne une destination de journalisation. C’est l’obligation de télémétrie sûre définie dans la politique de journalisation du projet. Le sidecar d’accélération est un processus distinct atteint via un transport. La méthode de requête transporte des déclarations de portée pour l’autorisation. Un déploiement doit traiter la frontière du sidecar comme une frontière de confiance. Une politique de dégradation réglée sur Permissive peut masquer une perte de capacité pertinente pour la sécurité. Utilise Strict là où la justesse de la sortie fait partie des contrôles. Traite le contexte d’exception, les événements de job et les réponses du sidecar comme des données susceptibles d’être journalisées, et nettoie-les en conséquence.
Conformité
Section intitulée « Conformité »Cette page ne formule aucune revendication normative directe. Les contrats d’observabilité exposent l’état du moteur et n’implémentent pas de protocole standardisé dont le moteur devrait citer les clauses. Les obligations de télémétrie sûre et de nettoyage des journaux mentionnées ci-dessus découlent de la politique de journalisation interne du projet, pas d’une norme externe. Quand une opération observée est elle-même standardisée, comme une signature ou un document PDF/A, sa conformité est documentée sur la page de signature ou d’extraction.
Voir aussi
Section intitulée « Voir aussi »- Contrats : 41 interfaces publiques (SPI) — la vue d’ensemble du SPI et de ses niveaux de stabilité.
- Observabilité — le module d’état d’exécution exposé par ces contrats.
- Accélérateur — le client du sidecar Spectrum derrière
SpectrumInterface. - Exception — les exceptions qui implémentent
ContextAwareExceptionInterface. - Performances — les budgets auxquels le travail observé est soumis.