Contratti / Osservabilità
In breve
Sezione intitolata “In breve”Il dominio dell’osservabilità raccoglie i contratti che espongono lo stato di runtime del motore: ContextAwareExceptionInterface per il contesto strutturato degli errori, SpectrumInterface per il sidecar di accelerazione opzionale, JobNotificationInterface per l’avanzamento dei job in streaming e l’enum DegradationPolicy per il comportamento in caso di perdita di funzionalità.
Installazione
Sezione intitolata “Installazione”composer require nextpdf/core:^3Panoramica concettuale
Sezione intitolata “Panoramica concettuale”ContextAwareExceptionInterface è il contratto diagnostico. Ogni eccezione di dominio di NextPDF lo implementa. Qualsiasi eccezione di NextPDF intercettata può essere convertita a tale interfaccia per recuperare il contesto strutturato destinato a uno strumento di Application Performance Monitoring (APM), a una pipeline di logging o a un reporter di errori. Il contesto è un array associativo con chiavi in snake_case e solo valori primitivi. Non contiene oggetti annidati. Per questo motivo può essere serializzato in un payload JSON o APM senza esiti inattesi. Ciò elimina la necessità di analizzare il messaggio di un’eccezione per recuperare i dati diagnostici. È stable dalla versione 3.1.0.
SpectrumInterface è il contratto per il sidecar di accelerazione opzionale. Spectrum è un motore parallelizzato sulla CPU che delega il rilevamento dell’hardware, il parsing dei PDF e la compressione delle immagini a un processo sidecar locale. Il contratto segnala la disponibilità dietro un circuit breaker, così che un controllo di integrità frequente non propaghi a cascata un errore quando il sidecar non è attivo. Esegue la sonda delle funzionalità hardware con un risultato memorizzato nella cache. Espone il budget di risorse attivo. Fornisce un trasporto di richieste generico per i moduli di livello superiore. Il motore funziona anche senza il sidecar. Il contratto esiste affinché l’accelerazione sia un’opzione iniettabile e non una dipendenza obbligatoria. JobNotificationInterface trasmette in streaming eventi di job tipizzati dall’endpoint server-sent events del sidecar come generator. Il generator termina quando arriva un evento terminale o quando il flusso si chiude.
DegradationPolicy è l’enum di comportamento per la perdita di funzionalità. Quando una funzionalità si degrada, il criterio decide se sollevare un’eccezione, emettere un avviso o registrare in modo silenzioso, tenendo conto dell’impatto. Strict solleva un’eccezione quando l’impatto è un rischio di conformità, una perdita semantica o un blocco. È la scelta indicata per un ambiente regolamentato in cui la correttezza dell’output è obbligatoria. Balanced, l’opzione predefinita, emette avvisi strutturati e prosegue in caso di degradazione limitata, sollevando un’eccezione solo in caso di impatto bloccante. È la scelta indicata per la maggior parte dei deployment in produzione. Permissive registra ogni evento in modo silenzioso e non solleva mai eccezioni. È la scelta indicata per una modalità di anteprima o bozza in cui è accettabile un output best-effort. I tipi SpectrumInterface, JobNotificationInterface e DegradationPolicy sono experimental. La loro garanzia di compatibilità è più debole rispetto a ContextAwareExceptionInterface.
Superficie dell’API
Sezione intitolata “Superficie dell’API”| Tipo | Categoria | Membri principali | Stabilità | Dalla versione |
|---|---|---|---|---|
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 | enum (string) | Strict, Balanced, Permissive | experimental | 2.3.0 |
getContext() restituisce soltanto valori primitivi o liste di valori primitivi. streamEvents() produce oggetti JobEvent fino a un evento terminale. SpectrumInterface::request() restituisce il corpo grezzo della risposta come string. probe() restituisce un HardwareReport e getBudget() restituisce un SpectrumBudget.
Esempio di codice — Avvio rapido
Sezione intitolata “Esempio di codice — Avvio rapido”<?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());}Il contesto strutturato viene inserito nel record di log senza analizzare il messaggio.
Esempio di codice — Produzione
Sezione intitolata “Esempio di codice — Produzione”<?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 ''; }}Il tipo SpectrumInterface nullable rende l’accelerazione opzionale. Il contratto espone un unico metodo di trasporto, request(), che restituisce il corpo grezzo della risposta come string. Un parser di livello superiore converte tale corpo in un NextPDF\Accelerator\BatchResult. La classe concreta SpectrumClient aggiunge helper tipizzati come parseBatch() che incapsulano request() e restituiscono direttamente BatchResult. Tali helper non fanno parte del contratto bloccato. Il criterio di degradazione decide se l’assenza del sidecar è fatale.
Casi limite e insidie
Sezione intitolata “Casi limite e insidie”- Non tutti i
\Throwablesono eccezioni di NextPDF. Verificare sempre coninstanceof ContextAwareExceptionInterfaceprima di chiamaregetContext(). getContext()restituisce per contratto soltanto valori primitivi. Un consumatore che si aspetta oggetti annidati parte da un presupposto errato; il contratto garantisce valori JSON-safe.SpectrumInterface::isAvailable()è protetto da un circuit breaker ed è sicuro da chiamare di frequente, ma un risultatotrueè un controllo riferito a un dato istante. Gestire il caso in cui il sidecar si interrompa tra il controllo e la chiamata.JobNotificationInterface::streamEvents()è un generator. Iterarlo due volte non riproduce nuovamente gli eventi. Consumarlo una sola volta.DegradationPolicy::Permissivenon solleva mai eccezioni. In quella modalità una degradazione che incide sulla conformità passa sotto silenzio. Non utilizzarla per output regolamentato.
Prestazioni
Sezione intitolata “Prestazioni”I contratti di osservabilità aggiungono un costo trascurabile. getContext() restituisce un array pre-costruito. isAvailable() è una sonda di integrità memorizzata nella cache e protetta da circuit breaker. Il contratto richiede che le implementazioni memorizzino nella cache il risultato della sonda per almeno 30 secondi, affinché un percorso critico non chiami ripetutamente il sidecar. streamEvents() è limitato dalla frequenza degli eventi del sidecar, non dal motore. Il performance_budget di 1500 ms di tempo reale e 64 MB di picco è determinato dal lavoro sottostante osservato dai contratti, non dai contratti stessi. Il profilo di riproducibilità è structural. Un flusso di eventi e un contesto di eccezione includono timestamp. Due esecuzioni differiscono in quei campi, mentre la struttura rimane identica.
Note sulla sicurezza
Sezione intitolata “Note sulla sicurezza”Il contesto strutturato delle eccezioni è una superficie di esfiltrazione di dati se contiene segreti. Il contratto limita il contesto ai valori primitivi, riducendo la fuga accidentale di oggetti. Un deployment deve comunque ripulire i valori sensibili prima che il contesto raggiunga un sink di log. Questo è l’obbligo di telemetria sicura previsto dal criterio di logging del progetto. Il sidecar di accelerazione è un processo separato raggiunto tramite un trasporto. Il metodo di richiesta veicola le claim di ambito per l’autorizzazione. Un deployment deve trattare il confine del sidecar come un confine di attendibilità. Un criterio di degradazione impostato su Permissive può mascherare una perdita di funzionalità rilevante per la sicurezza. Utilizzare Strict dove la correttezza dell’output costituisce un controllo. Trattare il contesto delle eccezioni, gli eventi dei job e le risposte del sidecar come dati che possono essere registrati e ripulirli di conseguenza.
Conformità
Sezione intitolata “Conformità”Questa pagina non formula alcuna dichiarazione normativa diretta. I contratti di osservabilità espongono lo stato del motore e non implementano un protocollo standardizzato le cui clausole il motore debba citare. Gli obblighi di telemetria sicura e di ripulitura dei log citati in precedenza derivano dal criterio di logging interno del progetto e non da uno standard esterno. Quando un’operazione osservata è essa stessa standardizzata — una firma, un documento PDF/A — la sua conformità è documentata nella pagina di firma o di estrazione.
Vedere anche
Sezione intitolata “Vedere anche”- Contratti: 41 interfacce pubbliche (SPI) — panoramica delle SPI e dei livelli di stabilità.
- Osservabilità — il modulo di stato di runtime esposto da questi contratti.
- Accelerator — il client del sidecar Spectrum dietro
SpectrumInterface. - Exception — eccezioni che implementano
ContextAwareExceptionInterface. - Performance — i budget rispetto ai quali viene eseguito il lavoro osservato.