Bỏ qua để đến nội dung

Contracts / Observability

Miền observability định nghĩa các contract phơi bày trạng thái lúc chạy của engine: ContextAwareExceptionInterface cho ngữ cảnh lỗi có cấu trúc, SpectrumInterface cho sidecar tăng tốc tùy chọn, JobNotificationInterface cho tiến trình tác vụ truyền theo luồng, và enum DegradationPolicy cho hành vi khi mất khả năng.

Terminal window
composer require nextpdf/core:^3

ContextAwareExceptionInterface là contract chẩn đoán. Mọi exception miền của NextPDF đều triển khai contract này. Bạn có thể ép kiểu bất kỳ exception NextPDF nào đã bắt được sang contract này và lấy ngữ cảnh có cấu trúc cho một công cụ Application Performance Monitoring (APM), một pipeline ghi nhật ký, hoặc một bộ báo cáo lỗi. Ngữ cảnh là một associative array chỉ chứa khóa snake_case và giá trị nguyên thủy. Nó không chứa object lồng nhau. Nhờ đó, ngữ cảnh có thể được tuần tự hóa một cách dự đoán được thành một payload JavaScript Object Notation (JSON) hoặc một payload APM. Bạn không cần phân tích thông báo exception để khôi phục dữ liệu chẩn đoán. Contract này ở mức stable kể từ 3.1.0.

SpectrumInterface là contract dành cho sidecar tăng tốc tùy chọn. Spectrum chạy công việc song song trên central processing unit (CPU), chuyển việc phát hiện phần cứng, phân tích Portable Document Format (PDF) và nén ảnh sang một tiến trình sidecar cục bộ. Contract báo cáo tính khả dụng qua một circuit breaker, vì vậy việc kiểm tra tình trạng thường xuyên không làm sự cố lan rộng khi sidecar gặp lỗi. Nó thăm dò khả năng phần cứng và lưu kết quả vào bộ nhớ đệm. Nó phơi bày ngân sách tài nguyên đang hoạt động. Nó cũng cung cấp một transport yêu cầu chung cho các module cấp cao hơn. Engine vẫn hoạt động khi không có sidecar. Contract biến tăng tốc thành một tùy chọn có thể inject, chứ không phải một phụ thuộc bắt buộc. JobNotificationInterface truyền theo luồng các sự kiện tác vụ có kiểu từ endpoint server-sent-events của sidecar dưới dạng một generator. Generator dừng lại khi xuất hiện sự kiện kết thúc hoặc khi luồng đóng lại.

DegradationPolicy là enum hành vi khi mất khả năng. Khi một khả năng bị giảm cấp, chính sách sẽ quyết định ném lỗi, cảnh báo, hay thu thập trong im lặng, dựa trên mức tác động. Strict ném lỗi khi tác động là một rủi ro tuân thủ, một tổn thất ngữ nghĩa, hoặc gây nghẽn. Hãy dùng nó trong môi trường được quản lý chặt, nơi tính đúng đắn của đầu ra là bắt buộc. Balanced, giá trị mặc định, phát ra cảnh báo có cấu trúc và tiếp tục với mức giảm cấp có giới hạn, đồng thời chỉ ném lỗi khi tác động gây nghẽn. Hãy dùng nó cho hầu hết các triển khai production. Permissive thu thập mọi sự kiện trong im lặng và không bao giờ ném lỗi. Hãy dùng nó cho chế độ xem trước hoặc bản nháp, nơi đầu ra ở mức nỗ lực tối đa là chấp nhận được. Các kiểu SpectrumInterface, JobNotificationInterfaceDegradationPolicy ở mức experimental. Cam kết tương thích của chúng yếu hơn so với ContextAwareExceptionInterface.

KiểuLoạiThành viên chínhĐộ ổn địnhTừ phiên bản
ContextAwareExceptionInterfaceinterfacegetContext(): array<string, mixed>stable3.1.0
SpectrumInterfaceinterfaceisAvailable(), probe(), getBudget(), request()experimental2.1.0
JobNotificationInterfaceinterfacestreamEvents(string): Generator<int, JobEvent>experimental2.2.0
DegradationPolicyenum (string)Strict, Balanced, Permissiveexperimental2.3.0

getContext() chỉ trả về giá trị nguyên thủy hoặc danh sách giá trị nguyên thủy. streamEvents() sinh ra các object JobEvent cho đến khi có sự kiện kết thúc. SpectrumInterface::request() trả về phần thân phản hồi thô dưới dạng một string. probe() trả về một HardwareReport, và getBudget() trả về một SpectrumBudget.

examples/contracts/observability-quickstart.php
<?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());
}

Ngữ cảnh có cấu trúc được đưa vào bản ghi nhật ký mà không cần phân tích thông báo.

examples/contracts/observability-production.php
<?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 '';
}
}

Giao diện SpectrumInterface nullable giúp việc tăng tốc trở thành tùy chọn. Contract phơi bày một phương thức transport, request(), trả về phần thân phản hồi thô dưới dạng một string. Một parser cấp cao hơn chuyển phần thân đó thành một NextPDF\Accelerator\BatchResult. SpectrumClient cụ thể bổ sung các hàm trợ giúp có kiểu như parseBatch() bao bọc request() và trả về trực tiếp BatchResult. Các hàm trợ giúp đó không thuộc phần contract đã đóng băng. Chính sách giảm cấp quyết định việc thiếu sidecar có nghiêm trọng hay không.

  • Không phải mọi \Throwable đều là exception NextPDF. Hãy bảo vệ bằng instanceof ContextAwareExceptionInterface trước khi gọi getContext().
  • getContext() chỉ trả về giá trị nguyên thủy theo contract. Nếu bạn mong đợi object lồng nhau thì giả định đó là sai; contract bảo đảm các giá trị an toàn với JSON.
  • SpectrumInterface::isAvailable() chạy sau một circuit breaker và an toàn để gọi thường xuyên, nhưng kết quả true chỉ là một lần kiểm tra tại một thời điểm. Hãy xử lý tình huống sidecar ngừng hoạt động giữa lúc kiểm tra và lúc gọi.
  • JobNotificationInterface::streamEvents() là một generator. Lặp qua nó hai lần sẽ không phát lại các sự kiện. Hãy dùng nó một lần duy nhất.
  • DegradationPolicy::Permissive không bao giờ ném lỗi. Ở chế độ đó, một lần giảm cấp ảnh hưởng đến tuân thủ sẽ đi qua trong im lặng. Đừng dùng nó cho đầu ra được quản lý chặt.

Các contract observability thêm chi phí không đáng kể. getContext() trả về một array đã được dựng sẵn. isAvailable() là một phép thăm dò tình trạng có lưu đệm và có circuit breaker. Contract yêu cầu các triển khai lưu đệm kết quả thăm dò trong ít nhất 30 giây, để một đường thực thi nóng không gọi sidecar lặp đi lặp lại. streamEvents() bị giới hạn bởi tốc độ sự kiện của sidecar, không phải bởi engine. performance_budget 1500 ms thời gian thực và 64 MB đỉnh được đặt theo công việc nền tảng mà các contract quan sát, không phải theo chính các contract. Hồ sơ khả năng tái lập là structural. Luồng sự kiện và ngữ cảnh exception bao gồm timestamp. Hai lần chạy sẽ khác nhau ở những trường đó, trong khi cấu trúc vẫn giữ nguyên.

Ngữ cảnh exception có cấu trúc là một bề mặt rò rỉ dữ liệu nếu nó mang theo thông tin bí mật. Contract giới hạn ngữ cảnh chỉ ở giá trị nguyên thủy, qua đó hạn chế rò rỉ object ngoài ý muốn. Bạn vẫn phải làm sạch các giá trị nhạy cảm trước khi ngữ cảnh đến được nơi nhận nhật ký. Đây là nghĩa vụ telemetry an toàn trong chính sách ghi nhật ký của dự án. Sidecar tăng tốc là một tiến trình riêng được truy cập qua một transport. Phương thức yêu cầu mang theo các scope claim để cấp quyền. Bạn phải coi ranh giới sidecar như một ranh giới tin cậy. Chính sách giảm cấp đặt thành Permissive có thể che giấu một mất mát khả năng liên quan đến bảo mật. Hãy dùng Strict ở nơi tính đúng đắn của đầu ra là một biện pháp kiểm soát. Hãy coi ngữ cảnh exception, sự kiện tác vụ và phản hồi sidecar là dữ liệu có thể bị ghi nhật ký, rồi làm sạch tương ứng.

Trang này không khẳng định tuyên bố quy phạm trực tiếp nào. Các contract observability phơi bày trạng thái engine và không triển khai giao thức chuẩn hóa nào khiến engine phải trích dẫn điều khoản. Các nghĩa vụ telemetry an toàn và làm sạch nhật ký được nhắc đến ở trên bắt nguồn từ chính sách ghi nhật ký nội bộ của dự án, không phải từ một tiêu chuẩn bên ngoài. Khi một thao tác được quan sát tự nó đã được chuẩn hóa — một chữ ký, một tài liệu PDF/A — thì sự tuân thủ của thao tác đó được tài liệu hóa trên trang ký hoặc trích xuất.

  • Contracts: 41 public interface (SPI) — tổng quan SPI và các mức ổn định.
  • Observability — module trạng thái lúc chạy mà các contract này phơi bày.
  • Accelerator — client sidecar Spectrum đứng sau SpectrumInterface.
  • Exception — các exception triển khai ContextAwareExceptionInterface.
  • Performance — các ngân sách mà công việc được quan sát phải tuân theo.