Kontrakty / Obserwowalność
W skrócie
Dział zatytułowany „W skrócie”Obszar obserwowalności definiuje kontrakty, które udostępniają stan silnika w czasie wykonywania: ContextAwareExceptionInterface dla ustrukturyzowanego kontekstu błędu, SpectrumInterface dla opcjonalnego procesu pomocniczego akceleracji, JobNotificationInterface dla strumieniowego postępu zadań oraz typ wyliczeniowy DegradationPolicy dla zachowania w razie utraty funkcji.
Instalacja
Dział zatytułowany „Instalacja”composer require nextpdf/core:^3Przegląd koncepcyjny
Dział zatytułowany „Przegląd koncepcyjny”ContextAwareExceptionInterface jest kontraktem diagnostycznym. Implementuje go każdy wyjątek domenowy NextPDF. Każdy przechwycony wyjątek NextPDF można rzutować na ten kontrakt i pobrać ustrukturyzowany kontekst dla narzędzia do monitorowania wydajności aplikacji (APM), potoku logowania albo reportera błędów. Kontekst jest tablicą asocjacyjną z kluczami w stylu snake_case i zawiera wyłącznie wartości prymitywne. Nie zawiera zagnieżdżonych obiektów. Dzięki temu serializuje się przewidywalnie do ładunku w formacie JavaScript Object Notation (JSON) lub ładunku APM. Nie trzeba parsować komunikatu wyjątku, aby odzyskać dane diagnostyczne. Jest stable od wersji 3.1.0.
SpectrumInterface jest kontraktem dla opcjonalnego procesu pomocniczego akceleracji. Spectrum wykonuje pracę równolegle na procesorze centralnym (CPU), przenosząc wykrywanie sprzętu, parsowanie formatu Portable Document Format (PDF) oraz kompresję obrazów do lokalnego procesu pomocniczego. Kontrakt raportuje dostępność za bezpiecznikiem (circuit breaker), więc częste kontrole stanu nie pogłębiają awarii, gdy proces pomocniczy nie działa. Sprawdza możliwości sprzętowe i zapisuje wynik w pamięci podręcznej. Udostępnia bieżący budżet zasobów. Zapewnia także ogólny transport żądań dla modułów wyższego poziomu. Silnik działa również bez procesu pomocniczego. Kontrakt sprawia, że akcelerację można wstrzyknąć jako opcję, zamiast traktować ją jako twardą zależność. JobNotificationInterface strumieniuje typowane zdarzenia zadań z punktu końcowego server-sent-events procesu pomocniczego jako generator. Generator kończy pracę, gdy nadejdzie zdarzenie końcowe lub strumień zostanie zamknięty.
DegradationPolicy jest typem wyliczeniowym określającym zachowanie w razie utraty funkcji. Gdy funkcja ulega degradacji, polityka na podstawie skutków decyduje, czy rzucić wyjątek, ostrzec, czy gromadzić zdarzenia po cichu. Strict rzuca wyjątek, gdy skutek oznacza ryzyko zgodności, utratę semantyki lub blokadę działania. Stosuj ją w środowiskach regulowanych, gdzie poprawność wyniku jest obowiązkowa. Balanced, wartość domyślna, emituje ustrukturyzowane ostrzeżenia i kontynuuje przy ograniczonej degradacji, a wyjątek rzuca tylko przy skutku blokującym. Stosuj ją w większości wdrożeń produkcyjnych. Permissive gromadzi każde zdarzenie po cichu i nigdy nie rzuca wyjątku. Stosuj ją w trybie podglądu lub szkicu, gdzie akceptowalny jest wynik realizowany na zasadzie best-effort. Typy SpectrumInterface, JobNotificationInterface oraz DegradationPolicy są experimental. Ich obietnica kompatybilności jest słabsza niż w przypadku ContextAwareExceptionInterface.
Powierzchnia API
Dział zatytułowany „Powierzchnia API”| Typ | Rodzaj | Kluczowe składowe | Stabilność | Od wersji |
|---|---|---|---|---|
ContextAwareExceptionInterface | interfejs | getContext(): array<string, mixed> | stable | 3.1.0 |
SpectrumInterface | interfejs | isAvailable(), probe(), getBudget(), request() | experimental | 2.1.0 |
JobNotificationInterface | interfejs | streamEvents(string): Generator<int, JobEvent> | experimental | 2.2.0 |
DegradationPolicy | enum (string) | Strict, Balanced, Permissive | experimental | 2.3.0 |
getContext() zwraca wyłącznie prymitywy lub listy prymitywów. streamEvents() generuje obiekty JobEvent aż do zdarzenia końcowego. SpectrumInterface::request() zwraca surową treść odpowiedzi jako string. probe() zwraca HardwareReport, a getBudget() zwraca SpectrumBudget.
Przykład kodu — szybki start
Dział zatytułowany „Przykład kodu — szybki start”<?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());}Ustrukturyzowany kontekst trafia do wpisu logu bez potrzeby parsowania komunikatu.
Przykład kodu — produkcja
Dział zatytułowany „Przykład kodu — produkcja”<?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 ''; }}Dopuszczenie wartości null dla SpectrumInterface sprawia, że akceleracja jest opcjonalna. Kontrakt udostępnia jedną metodę transportu, request(), która zwraca surową treść odpowiedzi jako string. Parser wyższego poziomu przekształca tę treść w NextPDF\Accelerator\BatchResult. Konkretny SpectrumClient dodaje typowane funkcje pomocnicze, takie jak parseBatch(), które opakowują request() i zwracają bezpośrednio BatchResult. Te funkcje pomocnicze nie są częścią zamrożonego kontraktu. Polityka degradacji rozstrzyga, czy brak procesu pomocniczego jest krytyczny.
Przypadki brzegowe i pułapki
Dział zatytułowany „Przypadki brzegowe i pułapki”- Nie każdy
\Throwablejest wyjątkiem NextPDF. Przed wywołaniemgetContext()zabezpiecz kod za pomocąinstanceof ContextAwareExceptionInterface. getContext()zgodnie z kontraktem zwraca wyłącznie prymitywy. Jeśli oczekujesz zagnieżdżonych obiektów, założenie jest błędne; kontrakt gwarantuje wartości bezpieczne dla JSON.SpectrumInterface::isAvailable()działa za bezpiecznikiem (circuit breaker) i można ją wywoływać często, ale wyniktrueoznacza kontrolę w danym punkcie czasu. Obsłuż sytuację, w której proces pomocniczy przestaje działać między kontrolą a wywołaniem.JobNotificationInterface::streamEvents()jest generatorem. Dwukrotne iterowanie po nim nie odtwarza zdarzeń. Skonsumuj go jednokrotnie.DegradationPolicy::Permissivenigdy nie rzuca wyjątku. W tym trybie degradacja wpływająca na zgodność przechodzi po cichu. Nie stosuj go dla wyniku podlegającego regulacjom.
Wydajność
Dział zatytułowany „Wydajność”Kontrakty obserwowalności dodają pomijalny koszt. getContext() zwraca wcześniej zbudowaną tablicę. isAvailable() to buforowana sonda stanu zabezpieczona bezpiecznikiem (circuit breaker). Kontrakt wymaga, aby implementacje buforowały wynik sondy przez co najmniej 30 sekund, więc ścieżka krytyczna nie wywołuje procesu pomocniczego wielokrotnie. Tempo streamEvents() wyznaczają zdarzenia procesu pomocniczego, a nie silnik. Wartość performance_budget wynosząca 1500 ms czasu rzeczywistego i 64 MB szczytowego zużycia jest wyznaczana przez bazową pracę, którą kontrakty obserwują, a nie przez same kontrakty. Profil odtwarzalności to structural. Strumienie zdarzeń i konteksty wyjątków zawierają znaczniki czasu. Dwa uruchomienia różnią się w tych polach, podczas gdy struktura pozostaje identyczna.
Uwagi dotyczące bezpieczeństwa
Dział zatytułowany „Uwagi dotyczące bezpieczeństwa”Ustrukturyzowany kontekst wyjątku jest powierzchnią wycieku danych, jeśli zawiera sekrety. Kontrakt ogranicza kontekst do prymitywów, co ogranicza przypadkowy wyciek obiektów. Mimo to musisz wyczyścić wrażliwe wartości, zanim kontekst trafi do odbiornika logów. Jest to obowiązek bezpiecznej telemetrii w polityce logowania projektu. Proces pomocniczy akceleracji to odrębny proces dostępny za pośrednictwem transportu. Metoda żądania przenosi deklaracje zakresu na potrzeby autoryzacji. Musisz traktować granicę procesu pomocniczego jako granicę zaufania. Polityka degradacji ustawiona na Permissive może maskować utratę funkcji istotną dla bezpieczeństwa. Stosuj Strict tam, gdzie poprawność wyniku stanowi mechanizm kontrolny. Traktuj kontekst wyjątku, zdarzenia zadań oraz odpowiedzi procesu pomocniczego jako dane, które mogą zostać zalogowane, i odpowiednio je czyść.
Zgodność
Dział zatytułowany „Zgodność”Ta strona nie formułuje bezpośredniego twierdzenia normatywnego. Kontrakty obserwowalności udostępniają stan silnika i nie implementują znormalizowanego protokołu, którego klauzule silnik musiałby przytaczać. Wspomniane powyżej obowiązki bezpiecznej telemetrii i czyszczenia logów wynikają z wewnętrznej polityki logowania projektu, a nie z zewnętrznego standardu. Gdy sama obserwowana operacja jest znormalizowana — podpis, dokument PDF/A — jej zgodność jest udokumentowana na stronie dotyczącej podpisywania lub ekstrakcji.
Zobacz także
Dział zatytułowany „Zobacz także”- Kontrakty: 41 publicznych interfejsów (SPI) — przegląd SPI i poziomów stabilności.
- Obserwowalność — moduł stanu w czasie wykonywania, który udostępniają te kontrakty.
- Accelerator — klient procesu pomocniczego Spectrum stojący za
SpectrumInterface. - Exception — wyjątki, które implementują
ContextAwareExceptionInterface. - Performance — budżety, względem których działa obserwowana praca.