Chaos: منظومة حتمية لسيناريوهات المرونة
لمحة سريعة
قسم بعنوان «لمحة سريعة»وحدة Chaos هي منظومة مدمجة لاختبار المرونة. تسجِّل سيناريوهات حقن الأعطال التي تنفِّذ واجهة تضم طريقة واحدة، ثم تُشغِّلها وتجمع تقرير pass/fail منظَّمًا. وتبقى صغيرة عمدًا، بخمس فئات، ومكانها الطبيعي هو مجموعات اختبار المرونة وتمارين يوم الفوضى، لا مسار إنتاج المستندات.
الاستقرار: تجريبي. هذه أداة للاختبار والمرونة، وليست واجهة API أساسية لتنسيق مستندات PDF. واجهة موفّر الخدمة (SPI) صغيرة وذات شكل مستقر، لكن نطاق الوحدة والسيناريوهات المرفقة بها يتطوران. لا تَبْنِ تدفق تحكم إنتاجي يعتمد عليها.
التثبيت
قسم بعنوان «التثبيت»composer require nextpdf/core:^3نظرة مفاهيمية عامة
قسم بعنوان «نظرة مفاهيمية عامة»يتحقق اختبار المرونة من أن المحرك يتدهور على نحو صحيح عند فشل إحدى الاعتماديات. تمنح وحدة Chaos هذا الاختبار بنية واضحة. ChaosScenarioInterface هي عقد السيناريو: تحدِّد name() هوية السيناريو، وتُعيد simulate() كائن ChaosOutcome. يغلِّف كل سيناريو عطلًا واحدًا، مثل انقسام الشبكة أو دفقة من استجابات 5xx من واجهة الاسترجاع الخلفية، ويُبلِغ بما حدث.
ChaosScenarioRunner يُنسِّق التشغيل. سجِّل السيناريوهات عبر register()، واستدعِ run() لتنفيذها بالتسلسل وفق ترتيب التسجيل، ثم اقرأ الإجماليات عبر outcomes() وallPassed() وpassCount() وfailCount(). لا يرمي المُشغِّل استثناءً مطلقًا عند فشل سيناريو: الفشل بيانات مُلتقَطة في كائن ChaosOutcome، لا استثناء. ولا يرمي استثناءً إلا عند تعطُّل بنيته التحتية ذاتها، مثل تسجيل سيناريو غير صالح أو تعذُّر كتابة ملف التقرير (ChaosReportWriteException). السيناريو الذي يتعذَّر عليه الوصول إلى المورد الذي يختبره يُظهِر RetrievalUnavailableException. الوحدة @since 3.2.0.
ChaosOutcome يخزِّن نتيجة كل سيناريو: حالة pass/fail، والمدة، ومُخرَج toArray() للتقرير المنظَّم. ولأن النتيجة تسجِّل مدة زمن الساعة الفعلي، فإن سمة قابلية إعادة إنتاج التقرير هي structural، لا bitwise.
واجهة API
قسم بعنوان «واجهة API»| النوع | الأعضاء الرئيسيون | الدور |
|---|---|---|
ChaosScenarioInterface | name(): string، simulate(): ChaosOutcome | عقد السيناريو (@since 3.2.0) |
ChaosScenarioRunner | register()، run()، outcomes()، allPassed()، passCount()، failCount() | مُنسِّق سيناريوهات تسلسلي (@since 3.2.0) |
ChaosOutcome | durationSeconds()، toArray() | نتيجة pass/fail لكل سيناريو (@since 3.2.0) |
RetrievalUnavailableException | — | تعذَّر الوصول إلى مورد قيد الاختبار |
ChaosReportWriteException | — | تعذَّرت كتابة ملف التقرير |
شغِّل composer docs:generate-api-php -- --module=Chaos لتوليد جدول PHPDoc الكامل.
نموذج برمجي — بداية سريعة
قسم بعنوان «نموذج برمجي — بداية سريعة»سجِّل سيناريو، ثم شغِّل المجموعة.
<?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";نموذج برمجي — الإنتاج
قسم بعنوان «نموذج برمجي — الإنتاج»أدِر المنظومة من مهمة مرونة، وأرجِع رمز خروج غير صفري لأي فشل، دون السماح بأن يظهر فشل سيناريو في هيئة استثناء.
<?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; }}الحالات الحدّية والمزالق
قسم بعنوان «الحالات الحدّية والمزالق»run()لا يرمي استثناءً مطلقًا بسبب فشل سيناريو. الفشل مُسجَّل فيChaosOutcome. إذا أحطتrun()بـ try/catch متوقعًا الأعطال هناك، فلن ترصدها. اقرأfailCount()/allPassed()بدلًا من ذلك.- لا يرمي المُشغِّل استثناءً إلا عند أعطال البنية التحتية: تسجيل غير صالح، أو
ChaosReportWriteExceptionعندما تتعذَّر الكتابة في مسار التقرير. عالِج تلك الأعطال على نحو منفصل عن نتائج السيناريوهات. - تُشغَّل السيناريوهات بالتسلسل وفق ترتيب التسجيل. لا توجد معالجة متوازية. قد يكون للترتيب أهمية عندما تتشارك السيناريوهات حالة خارجية.
- هذه الوحدة مخصَّصة لاختبار المرونة. لا تستورد المُشغِّل إلى مسار إنتاج المستندات بوصفه آلية تحكُّم.
الأداء
قسم بعنوان «الأداء»يضيف المُشغِّل عبئًا ضئيلًا. سلوك السيناريو هو ما يحدِّد التكلفة. ولأن السيناريوهات تحقن الأعطال وقد تنتظر انتهاء المهل الزمنية، فقد يكون تشغيل الفوضى بطيئًا بحكم التصميم. performance_budget هنا هو الرقم المرجعي للمحرك، لا حدًّا لمدة السيناريو. سمة قابلية إعادة الإنتاج هي structural: يسجِّل التقرير مدد زمن الساعة الفعلي، لذا تختلف تلك الحقول بين التشغيلات.
ملاحظات أمنية
قسم بعنوان «ملاحظات أمنية»تحقن السيناريوهات الأعطال وقد تختبر مسارات الفشل في الاعتماديات. شغِّل المنظومة في بيئة اختبار أو تجهيز فقط، ببيانات اعتماد ونقاط نهاية مقيَّدة بتلك البيئة. لا تشغِّلها مطلقًا على أنظمة الإنتاج. قد يحتوي التقرير على تفاصيل تشخيصية عن أنماط الفشل. تعامل معه باعتباره داخليًا، وطبِّق التزام المشروع بتنقية السجلّات قبل مشاركته. راجع نموذج تهديد المحرك في /modules/core/security/.
المطابقة
قسم بعنوان «المطابقة»لا تقدِّم هذه الوحدة أي ادعاء معياري بشأن مواصفة PDF. إنها أداة مرونة. ولا تنفِّذ أي بروتوكول معياري يجب الاستشهاد ببنوده. يتولى الأوراكل والمجموعات الذهبية الموصوفة في /modules/core/conformance/ التحقق من مطابقة المحرك.
انظر أيضًا
قسم بعنوان «انظر أيضًا»- وحدة قابلية الملاحظة — سطح حالة وقت التشغيل الذي يلاحظه السيناريو.
- وحدة المُسرِّع — هدف شائع لسيناريوهات فشل الاعتماديات.
- نظرة عامة على المطابقة
- نموذج أمان المحرك