Chaos: arcabouço determinístico para cenários de resiliência
Visão geral
Seção intitulada “Visão geral”O módulo Chaos é um arcabouço compacto para testes de resiliência. Você registra cenários de injeção de falhas que implementam uma interface de método único, executa esses cenários e consolida um relatório estruturado de pass/fail. Ele permanece deliberadamente pequeno, com cinco classes, e pertence a suítes de resiliência e exercícios de chaos-day, não ao caminho de produção de documentos.
Estabilidade: experimental. Esta é uma superfície de ferramentas de teste e resiliência, não a interface de programação de aplicações (API) central do Portable Document Format (PDF). A interface de provedor de serviços (SPI) é pequena e tem formato estável, mas o escopo do módulo e os cenários incluídos evoluem. Não construa fluxo de controle de produção sobre este módulo.
Instalação
Seção intitulada “Instalação”composer require nextpdf/core:^3Visão conceitual
Seção intitulada “Visão conceitual”Um teste de resiliência verifica se o motor se degrada corretamente quando uma dependência falha. O módulo Chaos dá estrutura a esse teste. ChaosScenarioInterface é o contrato do cenário: name() identifica o cenário, e simulate() retorna um ChaosOutcome. Cada cenário encapsula uma falha, como uma partição de rede ou uma rajada de respostas 5xx do backend de recuperação, e informa o que aconteceu.
ChaosScenarioRunner orquestra a execução. Você usa register() para registrar cenários, chama run() para executá-los sequencialmente na ordem de registro e, depois, lê o agregado com outcomes(), allPassed(), passCount() e failCount(). O executor nunca lança exceção por causa de uma falha de cenário: uma falha é um dado capturado em um ChaosOutcome, não uma exceção. Ele só lança exceção quando a própria infraestrutura está quebrada, como um registro de cenário inválido ou a impossibilidade de gravar o arquivo de relatório (ChaosReportWriteException). Um cenário que não consegue acessar o recurso que está testando expõe uma RetrievalUnavailableException. O módulo está marcado como @since 3.2.0.
ChaosOutcome armazena o resultado de cada cenário: status pass/fail, duração e a saída de toArray() para o relatório estruturado. Como um resultado registra a duração em tempo real (wall-clock), o perfil de reprodutibilidade do relatório é structural, não bitwise.
Superfície da API
Seção intitulada “Superfície da API”| Tipo | Membros principais | Função |
|---|---|---|
ChaosScenarioInterface | name(): string, simulate(): ChaosOutcome | Contrato do cenário (@since 3.2.0) |
ChaosScenarioRunner | register(), run(), outcomes(), allPassed(), passCount(), failCount() | Orquestrador sequencial de cenários (@since 3.2.0) |
ChaosOutcome | durationSeconds(), toArray() | Resultado pass/fail por cenário (@since 3.2.0) |
RetrievalUnavailableException | — | O recurso testado estava inacessível |
ChaosReportWriteException | — | O arquivo de relatório não pôde ser gravado |
Execute composer docs:generate-api-php -- --module=Chaos para gerar a tabela completa de PHPDoc.
Exemplo de código — Início rápido
Seção intitulada “Exemplo de código — Início rápido”Registre um cenário e, em seguida, execute a suíte.
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Chaos\ChaosOutcome;use NextPDF\Chaos\ChaosScenarioInterface;use NextPDF\Chaos\ChaosScenarioRunner;
final class TimeoutScenario implements ChaosScenarioInterface{ public function name(): string { return 'dependency-timeout'; }
public function simulate(): ChaosOutcome { // Inject the fault, observe the engine's degradation, return the verdict. return new ChaosOutcome(/* name, passed, durationSeconds, details */); }}
$runner = new ChaosScenarioRunner();$runner->register(new TimeoutScenario());$runner->run();
echo $runner->allPassed() ? "Resilient.\n" : "{$runner->failCount()} scenario(s) failed.\n";Exemplo de código — Produção
Seção intitulada “Exemplo de código — Produção”Execute o arcabouço a partir de um job de resiliência e retorne um código de saída diferente de zero para qualquer falha, sem permitir que uma falha de cenário escape como exceção.
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Chaos\ChaosScenarioRunner;use NextPDF\Chaos\Exception\ChaosReportWriteException;use Psr\Log\LoggerInterface;
final readonly class ChaosJob{ /** @param list<\NextPDF\Chaos\ChaosScenarioInterface> $scenarios */ public function __construct( private array $scenarios, private LoggerInterface $logger, ) {}
public function run(string $reportPath): int { $runner = new ChaosScenarioRunner();
foreach ($this->scenarios as $scenario) { $runner->register($scenario); }
$runner->run(); // never throws on scenario failure
try { $runner->writeReport($reportPath); } catch (ChaosReportWriteException $e) { $this->logger->error('Chaos report could not be written.', ['error' => $e->getMessage()]);
return 2; }
return $runner->allPassed() ? 0 : 1; }}Casos extremos e pegadinhas
Seção intitulada “Casos extremos e pegadinhas”run()nunca lança exceção por um cenário ter falhado. Uma falha fica emChaosOutcome. Se você envolverrun()em um try/catch esperando falhas ali, você não as verá. Em vez disso, leiafailCount()/allPassed().- O executor lança exceção apenas em falhas de infraestrutura: um registro inválido ou uma
ChaosReportWriteExceptionquando o caminho do relatório não pode ser gravado. Trate essas falhas separadamente dos resultados dos cenários. - Os cenários são executados sequencialmente na ordem de registro. Não há paralelismo. A ordem pode fazer diferença quando os cenários compartilham estado externo.
- Este módulo é para testes de resiliência. Não importe o executor para o caminho de produção de documentos como mecanismo de controle.
Desempenho
Seção intitulada “Desempenho”O executor acrescenta sobrecarga desprezível. O comportamento do cenário determina o custo. Como os cenários injetam falhas e podem aguardar timeouts, uma execução de chaos pode ser lenta por concepção. O performance_budget aqui é o valor de referência do motor, não um limite para a duração do cenário. O perfil de reprodutibilidade é structural: o relatório registra durações em tempo real (wall-clock), portanto esses campos diferem entre execuções.
Notas de segurança
Seção intitulada “Notas de segurança”Os cenários injetam falhas e podem exercitar caminhos de falha em dependências. Execute o arcabouço apenas em um ambiente de teste ou de staging, com credenciais e endpoints restritos a esse ambiente. Nunca o execute contra sistemas de produção. O relatório pode conter detalhes de diagnóstico sobre modos de falha. Trate-o como interno e cumpra a obrigação de higienização de logs do projeto antes de compartilhá-lo. Consulte o modelo de ameaças do motor em /modules/core/security/.
Conformidade
Seção intitulada “Conformidade”Este módulo não faz nenhuma declaração normativa sobre a especificação do PDF. Ele fornece ferramentas de resiliência. Não implementa nenhum protocolo padronizado cujas cláusulas devam ser citadas. As suítes de oracle e golden descritas em /modules/core/conformance/ validam a conformidade do motor.
Veja também
Seção intitulada “Veja também”- Módulo Observability — a superfície de estado em tempo de execução que um cenário observa.
- Módulo Accelerator — um alvo comum para cenários de falha de dependência.
- Visão geral de conformidade
- Modelo de segurança do motor