アクセラレーター:Spectrum サイドカークライアント
アクセラレーターモジュールは、オプションのアウトオブプロセス・アクセラレーションサイドカーである Spectrum 向けの PHP 側クライアントです。これは堅牢化された HTTP クライアントであり、サーキットブレーカー、JSON Web Token(JWT)ケーパビリティトークン、一時的障害時の単発リトライ、ストリーミングされるジョブ進捗用の server-sent-events トランスポートを提供します。エンジンはこのモジュールなしでも動作します。このモジュールは、アクセラレーションを必須ではなく注入可能にするために存在します。
安定性:実験的(experimental)。 Spectrum はオプションのサイドカーであり、凍結された公開 API ではありません。これが実装する
SpectrumInterfaceは、 Contracts / Observability で実験的として文書化されています。 このクライアントも同じティアに従います。トランスポート、トークン形式、バジェット形状はマイナーバージョン間で変更される場合があります。
インストール
「インストール」という見出しのセクションcomposer require nextpdf/core:^3概念的な概要
「概念的な概要」という見出しのセクションSpectrum は、プロセッサ負荷の高い処理をローカルのサイドカープロセスへオフロードします。対象には、ハードウェア検出、PDF 解析、画像圧縮が含まれます。SpectrumClient は、凍結された NextPDF\Contracts\SpectrumInterface を実装する PSR-18 クライアントです。ハードコードされた HTTP スタックではなく、ClientInterface、RequestFactoryInterface、StreamFactoryInterface に依存します。
このクライアントは、信頼性の低い依存先を前提に設計されています。サーキットブレーカーは、3 回連続で失敗すると開きます。開いている間、isAvailable() は指数バックオフウィンドウ内で false を返すため、ホットパスがダウン中のサイドカーに連続してリクエストを送ることはありません。プローブ結果は、生存期間(TTL)付きでキャッシュされます。アプリケーションシークレットが設定されている場合、すべての送信リクエストにリクエストケーパビリティトークンが付与されます。そのトークンは、エンドポイントが必要とするケーパビリティにスコープされた短命の HS256 JWT です。有効期間は 120 秒、ハイコントロール認可モードでは 30 秒です。一時的な 5xx エラーおよびタイムアウトエラーは、1 回だけリトライされます。認証エラーおよび解析エラーはリトライされません。
SspectrumClient はインスタンスごとにステートフルです。サーキットブレーカーの状態とプローブキャッシュは共有されません。各 PHP-FPM ワーカーは、それぞれ独自のインスタンスを保持するべきです。バッチ結果は型付けされています。BatchResult は、BatchItemStatus を持つ BatchItem エントリ、成功率を持つ BatchSummary、オプションのトレース ID を保持します。HardwareReport と HardwareCapabilities は、検出されたハードウェアティアを表します。HardwareCapabilities::satisfies() は、ティア要件にプログラムで応答します。DegradePolicy 列挙型と AuthorizationMode 列挙型が、ケーパビリティ喪失時の挙動とトークンの厳格さを決定します。モジュール全体が @since 2.1.0 です。
API サーフェス
「API サーフェス」という見出しのセクション| 型 | 主なメンバー | 役割 |
|---|---|---|
SpectrumClient | isAvailable()、probe()、getBudget()、request() | SpectrumInterface を実装する PSR-18 サイドカークライアント |
BatchResult | getItems()、getSummary()、filterByStatus()、traceId() | 型付けされたバッチ結果 |
BatchItem / BatchItemStatus | isOk()、isSuccessful()、isRetryable() | 項目ごとの結果とステータス列挙型 |
BatchSummary | isFullSuccess()、successRate() | バッチサマリーの集計 |
HardwareReport | hasPro()、hasEnterprise()、isApiVersionCompatible() | 検出されたサイドカーのケーパビリティ |
HardwareCapabilities | hasGpu()、satisfies()、bestAvailableTier() | プログラムによるケーパビリティ分岐 |
DegradePolicy / AuthorizationMode | enum ケース | デグレード時の挙動とトークンの厳格さ |
完全な PHPDoc テーブルは、composer docs:generate-api-php -- --module=Accelerator を実行して確認してください。
コードサンプル — クイックスタート
「コードサンプル — クイックスタート」という見出しのセクションサイドカーに依存する前に、サーキットブレーカーを介してサイドカーをプローブします。
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Contracts\SpectrumInterface;
function describeAccelerator(SpectrumInterface $spectrum): string{ if ($spectrum->isAvailable() !== true) { return 'Accelerator unavailable; engine runs in pure-PHP mode.'; }
$report = $spectrum->probe();
return $report->hasEnterprise() ? 'Enterprise accelerator tier active.' : 'Standard accelerator tier active.';}コードサンプル — 本番環境
「コードサンプル — 本番環境」という見出しのセクションサイドカーが正常であればサイドカー経由でバッチを送信し、そうでないときはデグレードポリシーに従ってフォールバックします。
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Accelerator\DegradePolicy;use NextPDF\Contracts\SpectrumInterface;use Psr\Log\LoggerInterface;
final readonly class AcceleratedCompressor{ public function __construct( private ?SpectrumInterface $spectrum, private DegradePolicy $policy, private LoggerInterface $logger, ) {}
/** @param list<array{id: string, data: string}> $images @return string Raw sidecar body. */ public function compress(array $images): string { if ($this->spectrum?->isAvailable() === true) { return $this->spectrum->request('POST', '/v1/compress', json: ['images' => $images], scope: ['compress']); }
if ($this->policy === DegradePolicy::Strict) { throw new \RuntimeException('Accelerator required under the strict degrade policy.'); }
$this->logger->info('Spectrum unavailable; using PHP image path.');
return ''; }}エッジケースと落とし穴
「エッジケースと落とし穴」という見出しのセクションisAvailable()は、ある時点での、サーキットブレーカーを介したチェックです。trueの結果が、次の呼び出しまでにfalseになることがあります。その間に利用不能になるサイドカーに備えてください。- サーキットブレーカーとプローブキャッシュの状態は、インスタンス単位です。1 つの
SpectrumClientを複数のワーカーで共有すると、ブレーカーは正しく機能しません。各ワーカーにそれぞれ独自のインスタンスを割り当ててください。 - ケーパビリティトークンは短命です(120 秒、ハイコントロールモードでは 30 秒)。長時間実行される処理では、トークンを再利用せず、新しいトークンを取得しなければなりません。
- 認証エラーと解析エラーはリトライされません。リトライされるのは一時的な 5xx とタイムアウトだけで、それも 1 回のみです。それを超える冪等なリトライが行われると想定しないでください。
- null の
SpectrumInterfaceは、エラーではなく「アクセラレーターなし」という正当な状態です。それが致命的かどうかは、デグレードポリシーが決定します。
パフォーマンス
「パフォーマンス」という見出しのセクションクライアント自体のオーバーヘッドは無視できる程度です。処理はサイドカー内で行われます。サーキットブレーカーは、信頼性を支える主要な制御点であり、サイドカーがダウンしているときの無駄なラウンドトリップを抑えます。1500 ms(実時間)/ 64 MB(ピーク)という performance_budget は、エンジンの参照ワークロードであり、サイドカーのサービスレベル契約(SLA)ではありません。再現性プロファイルは structural です。バッチ結果はトレース ID とタイムスタンプを保持するため、2 回の実行ではそれらのフィールドが異なります。
セキュリティに関する注意
「セキュリティに関する注意」という見出しのセクションサイドカー境界はトラスト境界です。アプリケーションシークレットが設定されている場合、リクエストにはエンドポイントにスコープされた HS256 ケーパビリティトークンが付与されます。そのシークレットは、シークレットマネージャーから取得され、決してコミットされない資格情報として扱ってください。ハイコントロール認可モードは、機密性の高いエンドポイントに対してトークンの有効期間を 30 秒に短縮します。オペレーターが指定するサイドカー URL は、最初のリクエスト時ではなく、構成の構築時に検証されます。受け入れられるのは、空でないホストを持つ http:// および https://、または空でないソケットパスを持つ unix:// のみです。それ以外のスキーム(gopher://、file://、ftp:// など)やホストを持たないネットワーク URL は、構築時にフェイルクローズします。これは SSRF と予期しない送信に対する多層防御であり、設定を誤ったエンドポイントが HTTP クライアントに到達することは決してありません。サイドカーの応答は外部データです。エンジンに戻す前に、信頼できないものとして検証し、扱ってください。このページの legal-review-required 輸出管理クラスは、アクセラレーション機能が暗号化トランスポートを伴い、輸出管理レビュー待ちであることを反映しています。この機能を有効にしたビルドを再配布する前に、そのレビューを参照してください。
このモジュールは、PDF 仕様に関する規範的な主張を一切行いません。これは内部のアクセラレーションプロトコル向けの HTTP クライアントです。このプロトコルはエンジン定義であり、条項を引用する必要がある標準化プロトコルではありません。サイドカーが行う処理(PDF 解析、圧縮)に準拠上の側面がある場合、その準拠は該当するモジュールページに文書化され、/modules/core/conformance/ のオラクルおよびゴールデンスイートによって検証されます。
- Contracts / Observability — このクライアントが実装する
SpectrumInterface。 - Observability モジュール — アクセラレートされた処理を観測するためのランタイム状態サーフェス。
- Performance モジュール — アクセラレートされた処理の基準となるバジェット。
- エンジンのセキュリティモデル