رفتن به متن راهنما
همه‌ی راهنماها

مرجع API

همهٔ کلاس‌ها، رابط‌ها و enumهای عمومی Reqtide با امضای متدها و یک یادداشت کوتاه دربارهٔ کار هر متد. کنار راهنماها بخوانید.

برنامه Reqtide PHP 0.1.0آخرین بررسی زمان خواندن 37 دقیقه

در این صفحه

این صفحه سطح عمومی سه بستهٔ enaxon/reqtide، enaxon/reqtide-redis و enaxon/reqtide-guzzle را فهرست می‌کند. امضاها مستقیم از کد منبع خوانده می‌شوند، پس با نسخهٔ منتشرشده یکی هستند. نوع‌ها و متدهایی که internal علامت خورده‌اند در فهرست نیستند و هر زمان ممکن است تغییر کنند.

اگر هنوز با کتابخانه کار نکرده‌اید، از شروع به کار شروع کنید.

ساخت پایپ‌لاین

همهٔ کارهای لازم هنگام راه‌اندازی. PipelineBuilder پیکربندی را می‌سازد و اعتبارسنجی می‌کند، compileInMemory() وضعیت محلی فرایند را وصل می‌کند و نتیجه یک CompiledPipeline است که بارها از آن استفاده می‌کنید. همهٔ اعداد را شما تعیین می‌کنید: سازنده مقدار پیش‌فرض ندارد.

PipelineBuilder

سازندهٔ روان و تغییرناپذیر: هر فراخوانی یک سازندهٔ تازه برمی‌گرداند. متدهای profile()، partition() و attemptTimeout() الزامی هستند. هر سیاست فقط وقتی وجود دارد که متدش را صدا بزنید. مقدار نامعتبر، InvalidConfigurationException را با نام گزینه پرتاب می‌کند.

PHP
final class PipelineBuilder {
    public static function profile(string $id, string $version): self;
    public function partition(
        string $application,
        string $environment,
        string $subject,
        ?string $tenant = null,
    ): self;
    public function attemptTimeout(
        Duration $maximumDuration,
        AttemptTimeoutRequirement $requirement,
    ): self;
    public function retry(
        int $maxAttempts,
        BackoffMode $backoff,
        Duration $baseDelay,
        Duration $maximumDelay,
        JitterMode $jitter,
        ?Duration $minimumRemainingAttemptAllowance = null,
    ): self;
    public function retryBudget(
        int $capacityTokens,
        int $refillTokens,
        Duration $refillInterval,
        Duration $reservationLease,
    ): self;
    public function rateLimit(
        RateAlgorithmOptions $algorithm,
        int $cost = 1,
    ): self;
    public function circuitBreaker(
        CircuitWindowOptions $window,
        int $minimumSamples,
        Ratio $failureThreshold,
        Duration $openDuration,
        int $probeCapacity,
        int $probeSuccessThreshold,
        Duration $permitLease,
    ): self;
    public function bulkhead(int $capacity, Duration $lease): self;
    public function cooldown(
        Duration $cleanupGrace,
        ?Duration $maximumExtension = null,
    ): self;
    public function fallbackScope(FallbackScope $scope): self;
    public static function tokenBucket(
        int $capacity,
        int $refillTokens,
        Duration $refillInterval,
    ): TokenBucketOptions;
    public static function fixedWindow(
        int $capacity,
        Duration $window,
        FixedWindowAnchor $anchor,
    ): FixedWindowOptions;
    public static function slidingWindow(
        int $capacity,
        Duration $window,
    ): SlidingCounterOptions;
    public static function lastCalls(int $completedSamples): CountCircuitWindow;
    public static function timeWindow(
        Duration $window,
        Duration $bucketGranularity,
    ): TimeCircuitWindow;
    public function definition(): PipelineDefinition;
    public function compile(RuntimeEnvironment $environment): CompiledPipeline;
    public function compileInMemory(
        OutcomeClassifier $classifier,
        ?EventSink $events = null,
    ): CompiledPipeline;
}
  • profile() به پیکربندی نام و نسخه می‌دهد. وقتی تنظیمات عوض می‌شود، نسخه را هم عوض کنید. وضعیت مشترک با نسخه کلیدگذاری می‌شود.
  • partition() وضعیت مال چه کسی است: برنامه، محیط، موضوع و یک مستأجر اختیاری. هر پایپ‌لاین دقیقاً به یک پارتیشن خدمت می‌کند.
  • attemptTimeout() بیشترین زمانی که یک تلاش می‌تواند بگیرد. با runtime همگام از Cooperative استفاده کنید.
  • retry() تا maxAttempts تلاش، با احتساب تلاش اول. بیش از یک تلاش به retryBudget() و یک اعلام ایمنی تکرار در هر فراخوانی نیاز دارد.
  • retryBudget() یک مخزن توکن که هزینهٔ تلاش‌های مجدد را می‌پردازد تا به وابستگی خراب فشار بیش از حد نیاید.
  • rateLimit() برای هر ارسال، از جمله تلاش‌های مجدد، cost واحد کم می‌کند. نتیجهٔ tokenBucket()، fixedWindow() یا slidingWindow() را می‌گیرد.
  • circuitBreaker() یک پنجره از تماس‌های تمام‌شده را بررسی می‌کند، در سهم مشخصی از شکست‌ها باز می‌شود و پس از مدت باز بودن، آزمایش می‌کند.
  • bulkhead() حداکثر capacity عملیات هم‌زمان در جریان است. lease زمان اجارهٔ جایگاهی را محدود می‌کند که صاحبش ناپدید شده است.
  • cooldown() یک وقفهٔ مشترک پس از انتظاری که سرور اعلام کرده است. به طبقه‌بند (classifier) نیاز دارد که انتظار را گزارش کند.
  • fallbackScope() مشخص می‌کند راهکار جایگزین (Fallback) می‌تواند رد شدن در مرحلهٔ پذیرش را هم جایگزین کند یا نه.
  • tokenBucket() الگوریتم نرخ: ظرفیت و توکن‌هایی که در هر بازه پر می‌شوند.
  • fixedWindow() الگوریتم نرخ: ظرفیت در هر پنجره، با تراز بر مبدأ زمان یا بر اولین درخواست.
  • slidingWindow() الگوریتم نرخ: یک شمارندهٔ لغزان تقریبی.
  • lastCalls() پنجرهٔ مدارشکن روی N تماس تمام‌شدهٔ آخر.
  • timeWindow() پنجرهٔ مدارشکن روی یک بازهٔ زمانی که در سطل‌ها نگه داشته می‌شود.
  • definition() ترکیب را اعتبارسنجی می‌کند و PipelineDefinition تغییرناپذیر را برمی‌گرداند.
  • compile() روی یک RuntimeEnvironment دست‌ساز کامپایل می‌کند، مثلاً با ابزارهای آزمون.
  • compileInMemory() با ساعت واقعی، تأخیرهای واقعی (sleep) و بک‌اندهای حافظهٔ محلی فرایند کامپایل می‌کند. طبقه‌بند پیش‌فرض وجود ندارد.

CompiledPipeline

پایپ‌لاین قابل استفادهٔ مجدد. وضعیتی را نگه می‌دارد که محدودیت‌ها به آن وابسته‌اند، پس یک بار بسازید و مشترک استفاده کنید. وضعیت هیچ عملیاتی را در خود ندارد.

PHP
final class CompiledPipeline {
    public function newContext(
        Duration $timeout,
        ?OperationSafety $safety = null,
        ?FallbackOperation $fallback = null,
        ?Cancellation $cancellation = null,
        ?BoundedMetadata $attributes = null,
        OperationId|string|null $operationId = null,
        ?PartitionIdentity $partition = null,
    ): ExecutionContext;
    public function execute(
        callable $operation,
        ExecutionContext $context,
    ): mixed;
    public function executeDetailed(
        callable $operation,
        ExecutionContext $context,
    ): ExecutionCompletion;
    public function executeOperation(
        AttemptOperation $operation,
        ExecutionContext $context,
    ): mixed;
    public function executeOperationDetailed(
        AttemptOperation $operation,
        ExecutionContext $context,
    ): ExecutionCompletion;
    public function explain(): PipelineExplanation;
}
  • newContext() برای هر عملیات یک context: مهلت کل، اعلام ایمنی تکرار، راهکار جایگزین اختیاری، لغو و شناسهٔ عملیات.
  • execute() یک callable را از پایپ‌لاین رد می‌کند. مقدار شما را برمی‌گرداند، استثنای خودتان را بدون تغییر پرتاب می‌کند، یا یک رد شدن از طرف Reqtide را پرتاب می‌کند.
  • executeDetailed() همین اجرا، اما به‌جای پرتاب برای پیامدهای کسب‌وکاری یا سیاستی، یک ExecutionCompletion برمی‌گرداند.
  • executeOperation() مثل execute() است، برای شیء AttemptOperation به‌جای callable.
  • executeOperationDetailed() مثل executeDetailed() است، برای یک AttemptOperation.
  • explain() سیاست‌های پیکربندی‌شده و قابلیت‌های runtime را توصیف می‌کند. بدون I/O و بدون تغییر وضعیت.

InMemoryEnvironment

زمان اجرا (runtime) را برای یک فرایند وصل می‌کند: ساعت سیستم، زمان‌بندی که واقعاً می‌خوابد، تصادفی‌سازی امن و یک بک‌اند حافظه برای هر سیاست پیکربندی‌شده. compileInMemory() از همین استفاده می‌کند.

PHP
final class InMemoryEnvironment {
    public static function for(
        PipelineDefinition $definition,
        OutcomeClassifier $classifier,
        ?EventSink $events = null,
    ): RuntimeEnvironment;
}

PipelineExplanation

خروجی explain(): پروفایل، سیاست‌های فعال و یادداشت‌های قابلیت مانند physical_stop=not_guaranteed.

PHP
final readonly class PipelineExplanation {
    public function __construct(
        public ProfileId $profileId,
        public ProfileVersion $profileVersion,
        public array $enabledPolicies,
        public array $capabilityNotes,
    );
}

Duration

تعداد صحیح و نامنفی نانوثانیه. حساب با بررسی انجام می‌شود: سرریز خطا پرتاب می‌کند و هرگز دور نمی‌زند.

PHP
final readonly class Duration {
    public function __construct(public int $nanoseconds);
    public static function zero(): self;
    public static function nanoseconds(int $value): self;
    public static function microseconds(int $value): self;
    public static function milliseconds(int $value): self;
    public static function seconds(int $value): self;
    public function isZero(): bool;
    public function isPositive(): bool;
    public function add(self $other): self;
    public function subtract(self $other): self;
    public function saturatingSubtract(self $other): self;
    public function multiply(int $factor): self;
    public function min(self $other): self;
    public function max(self $other): self;
    public function compare(self $other): int;
    public function equals(self $other): bool;
    public function ceilMicroseconds(): int;
}

Ratio

یک کسر ساده‌شده در بازهٔ (0, 1] که با اعداد صحیح مقایسه می‌شود. برای آستانهٔ شکست مدارشکن به کار می‌رود.

PHP
final readonly class Ratio {
    public const MAX_COMPONENT = 9007199254740991;
    public function __construct(
        public PositiveInt $numerator,
        public PositiveInt $denominator,
    );
    public static function of(int $numerator, int $denominator): self;
}

اجرای یک عملیات

شیءهای هر عملیات. context مهلت کل و اعلام شما دربارهٔ تکرار فراخوانی را حمل می‌کند. callable شما یک AttemptContext دریافت می‌کند.

ExecutionContext

واقعیت‌های تغییرناپذیر یک عملیات منطقی. آن را با CompiledPipeline::newContext() بسازید. یک context را بین چند عملیات مشترک نکنید.

PHP
final readonly class ExecutionContext {
    public function __construct(
        public OperationId $operationId,
        public PartitionIdentity $partition,
        public Deadline $deadline,
        public Cancellation $cancellation,
        public OperationMetadata $metadata,
        public ?FallbackOperation $fallback,
    );
}

AttemptContext

در هر تلاش به callable شما داده می‌شود: شناسهٔ عملیات، شناسهٔ تلاش، شمارهٔ تلاش، مهلت، لغو و مهلت هر تلاش.

PHP
final readonly class AttemptContext {
    public function __construct(
        public OperationId $operationId,
        public AttemptId $attemptId,
        public int $dispatchedAttemptNumber,
        public Deadline $deadline,
        public Cancellation $cancellation,
        public Duration $attemptTimeout,
    );
}

OperationSafety

اعلام شما دربارهٔ تکرار یک فراخوانی. unsafe() پیش‌فرض است و تلاش مجدد را ممنوع می‌کند. دو مورد دیگر آن را مجاز می‌کنند.

PHP
final readonly class OperationSafety {
    public static function unsafe(): self;
    public static function replayableRead(ReplaySafetyContract $contract): self;
    public static function providerIdempotentMutation(
        ReplaySafetyContract $contract,
    ): self;
}
  • unsafe() پیش‌فرض. پایپ‌لاینی که بیش از یک تلاش مجاز می‌کند، از اجرا خودداری می‌کند.
  • replayableRead() اعلام می‌کنید که اجرای دوبارهٔ callable بی‌خطر است.
  • providerIdempotentMutation() اعلام می‌کنید که ارائه‌دهنده تغییرهای تکراری را حذف می‌کند.

ReplaySafetyContract

اعلام مکتوبی که پشت OperationSafety قرار دارد. Reqtide هرگز آن را راستی‌آزمایی نمی‌کند.

PHP
final readonly class ReplaySafetyContract {
    public static function forReadOnlyCallable(
        string $operationName,
        Duration $validFor,
        ?Clock $clock = null,
        ?array $retryableOutcomeCodes = null,
    ): self;
    public function __construct(
        public string $contractReference,
        public string $identityValue,
        public string $identityScope,
        public string $duplicateHandlingContract,
        public DateTimeImmutable $establishedAt,
        public DateTimeImmutable $validUntil,
        public Duration $retention,
        public ReplayPreparation $preparation,
        public array $retryableOutcomeCodes,
    );
}
  • forReadOnlyCallable() قرارداد را برای یک خواندن تکرارپذیر می‌سازد. فراخوانی شما همان اعلام است و بررسی نمی‌شود.

OperationSafetyKind

نوع ایمنی‌ای که یک عملیات دارد.

PHP
enum OperationSafetyKind: string {
    case Unsafe = 'unsafe';
    case ReplayableRead = 'replayable_read';
    case ProviderIdempotentMutation = 'provider_idempotent_mutation';
}

FallbackOperation

راهکار جایگزینی که با newContext() به یک عملیات وصل می‌کنید. نتیجهٔ اصلی را دریافت می‌کند.

PHP
interface FallbackOperation {
    public function invoke(Outcome $original, ExecutionContext $context): mixed;
}

FallbackScope

آنچه راهکار جایگزین می‌تواند جایگزین کند. حالت پیش‌فرض فقط پیامدهای کسب‌وکاری را جایگزین می‌کند.

PHP
enum FallbackScope: string {
    case BusinessOutcomesOnly = 'business_outcomes_only';
    case IncludeAdmissionRefusals = 'include_admission_refusals';
}

تعیین معنای یک نتیجه

سیاست‌ها بر اساس طبقه‌بندی هر تلاش عمل می‌کنند و شما تعیین می‌کنید شکست یعنی چه. ExceptionClassifier طبقه‌بند آماده است. برای هر چیزی که آن نمی‌تواند بیان کند، OutcomeClassifier را پیاده‌سازی کنید.

ExceptionClassifier

طبقه‌بندی که با فهرست کلاس‌های استثنا کار می‌کند. عمداً محافظه‌کار است: استثنایی که کسی فهرستش نکرده، دوباره تلاش نمی‌شود و راهکار جایگزین هم جایش را نمی‌گیرد، ولی شکست مدارشکن حساب می‌شود. تطبیق با instanceof است. هر متد یک نمونهٔ تازه برمی‌گرداند.

PHP
final readonly class ExceptionClassifier implements OutcomeClassifier {
    public static function create(): self;
    public function retryOn(string ...$exceptionClasses): self;
    public function countAsCircuitFailure(string ...$exceptionClasses): self;
    public function ignoreForCircuit(string ...$exceptionClasses): self;
    public function fallbackOn(string ...$exceptionClasses): self;
    public function retryAfterFrom(callable $extractor): self;
    public function unacceptableValuesWhen(callable $predicate): self;
    public function classify(
        Outcome $outcome,
        OperationMetadata $metadata,
    ): OutcomeClassification;
}
  • create() یک طبقه‌بند خالی.
  • retryOn() کلاس‌های استثنایی که ممکن است دوباره تلاش شوند.
  • countAsCircuitFailure() شکست‌های مدارشکن را به این کلاس‌ها (و کلاس‌های قابل تلاش مجدد) محدود می‌کند. بدون آن، هر استثنایی که نادیده گرفته نشده باشد حساب می‌شود.
  • ignoreForCircuit() کلاس‌های استثنایی که دربارهٔ وابستگی چیزی نمی‌گویند، مثل خطاهای اعتبارسنجی. نادیده گرفتن بر فهرست شکست‌ها برتری دارد.
  • fallbackOn() کلاس‌های استثنایی که راهکار جایگزین می‌تواند جایشان را بگیرد.
  • retryAfterFrom() انتظار اعلام‌شدهٔ سرور (یک Duration یا null) را از یک استثنا بیرون می‌کشد.
  • unacceptableValuesWhen() مقدار برگردانده‌شده را شکست علامت می‌زند: شکست مدارشکن است، هرگز دوباره تلاش نمی‌شود و هرگز جایگزین نمی‌شود.
  • classify() قرارداد OutcomeClassifier.

OutcomeClassifier

قراردادی که یک طبقه‌بند پیاده‌سازی می‌کند. وقتی نتیجه‌ها را باید به شکلی دوباره تلاش یا طبقه‌بندی کنید که فهرست استثناها نمی‌تواند بگوید، طبقه‌بند خودتان را بنویسید.

PHP
interface OutcomeClassifier {
    public function classify(
        Outcome $outcome,
        OperationMetadata $metadata,
    ): OutcomeClassification;
}

Outcome

آنچه یک تلاش تولید کرد: یک مقدار برگردانده‌شده یا یک استثنای پرتاب‌شده.

PHP
final readonly class Outcome {
    public static function fromValue(
        mixed $value,
        BoundedMetadata $metadata,
    ): self;
    public static function fromException(
        Throwable $exception,
        BoundedMetadata $metadata,
    ): self;
    public function value(): mixed;
    public function exception(): Throwable;
}

OutcomeClassification

داوری طبقه‌بند دربارهٔ یک نتیجه: شایستگی تلاش مجدد، رأی مدارشکن، شایستگی راهکار جایگزین، قابل‌قبول بودن، یک کد دلیل و یک کران پایین اختیاری برای انتظار.

PHP
final readonly class OutcomeClassification {
    public function __construct(
        public RetryEligibility $retry,
        public CircuitVerdict $circuit,
        public FallbackEligibility $fallback,
        public Acceptability $acceptability,
        public string $reasonCode,
        public ?Duration $retryAfterLowerBound,
    );
}

OutcomeKind

اینکه نتیجه یک مقدار است یا یک استثنا.

PHP
enum OutcomeKind: string {
    case Value = 'value';
    case Exception = 'exception';
}

RetryEligibility

اینکه آیا نتیجه را می‌شود دوباره تلاش کرد.

PHP
enum RetryEligibility: string {
    case Eligible = 'eligible';
    case Ineligible = 'ineligible';
}

FallbackEligibility

اینکه آیا راهکار جایگزین می‌تواند جای نتیجه را بگیرد.

PHP
enum FallbackEligibility: string {
    case Eligible = 'eligible';
    case Ineligible = 'ineligible';
}

CircuitVerdict

اینکه نتیجه برای مدارشکن چطور حساب می‌شود. نتیجه‌های خنثی نه مدار را باز می‌کنند و نه آن را بهبود می‌دهند.

PHP
enum CircuitVerdict: string {
    case Success = 'success';
    case Failure = 'failure';
    case Neutral = 'neutral';
}

Acceptability

اینکه آیا نتیجه برای فراخواننده قابل‌قبول است.

PHP
enum Acceptability: string {
    case Acceptable = 'acceptable';
    case Unacceptable = 'unacceptable';
}

گزینه‌های سیاست

نوع‌های enum و شیءهای گزینه‌ای که سازنده می‌گیرد یا برمی‌گرداند. معمولاً از طریق PipelineBuilder به آن‌ها می‌رسید و کمتر پیش می‌آید که خودتان بسازیدشان.

BackoffMode

رشد تأخیر تلاش مجدد: ثابت یا نمایی.

PHP
enum BackoffMode: string {
    case Constant = 'constant';
    case Exponential = 'exponential';
}

JitterMode

حالت Full هر تأخیر را به‌طور یکنواخت بین صفر و تأخیر محاسبه‌شده انتخاب می‌کند.

PHP
enum JitterMode: string {
    case None = 'none';
    case Full = 'full';
}

AttemptTimeoutRequirement

برای runtime همگام، Cooperative انتخاب صادقانه است: کد شما باید به زمان احترام بگذارد. TransportEnforced runtime‌ای می‌خواهد که آن را اعلام کرده باشد.

PHP
enum AttemptTimeoutRequirement: string {
    case Cooperative = 'cooperative';
    case TransportEnforced = 'transport_enforced';
}

FixedWindowAnchor

جایی که پنجره‌های ثابت شروع می‌شوند: بر مضرب‌های طول پنجره، یا در اولین درخواست.

PHP
enum FixedWindowAnchor: string {
    case Aligned = 'aligned';
    case FirstHit = 'first_hit';
}

TokenBucketOptions

تنظیمات سطل توکن که PipelineBuilder::tokenBucket() برمی‌گرداند.

PHP
final readonly class TokenBucketOptions implements RateAlgorithmOptions {
    public function __construct(
        public PositiveInt $capacityUnits,
        public PositiveInt $refillUnits,
        public Duration $refillInterval,
    );
}

FixedWindowOptions

تنظیمات پنجرهٔ ثابت که PipelineBuilder::fixedWindow() برمی‌گرداند.

PHP
final readonly class FixedWindowOptions implements RateAlgorithmOptions {
    public function __construct(
        public PositiveInt $capacityUnits,
        public Duration $window,
        public FixedWindowAnchor $anchor,
    );
}

SlidingCounterOptions

تنظیمات شمارندهٔ لغزان که PipelineBuilder::slidingWindow() برمی‌گرداند.

PHP
final readonly class SlidingCounterOptions implements RateAlgorithmOptions {
    public function __construct(
        public PositiveInt $capacityUnits,
        public Duration $window,
    );
}

CountCircuitWindow

پنجرهٔ مدارشکن روی N تماس تمام‌شدهٔ آخر.

PHP
final readonly class CountCircuitWindow implements CircuitWindowOptions {
    public function __construct(public PositiveInt $completedSamples);
}

TimeCircuitWindow

پنجرهٔ مدارشکن روی یک بازهٔ زمانی که در سطل‌ها نگه داشته می‌شود.

PHP
final readonly class TimeCircuitWindow implements CircuitWindowOptions {
    public function __construct(
        public Duration $window,
        public Duration $bucketGranularity,
    );
}

نتایج یک عملیات

متد execute() مقدار شما را برمی‌گرداند یا پرتاب می‌کند. متد executeDetailed() همین واقعیت‌ها را به‌صورت داده در یک ExecutionCompletion برمی‌گرداند.

ExecutionCompletion

وضعیت پایان، نتیجهٔ نهایی، رکورد هر تلاش، اطلاعات عیب‌یابی محدود و خلاصه‌ای از شمارش‌ها.

PHP
final readonly class ExecutionCompletion {
    public function __construct(
        public CompletionDisposition $disposition,
        public ?Outcome $terminalOutcome,
        public ?Outcome $fallbackOutcome,
        public ?ReqtideException $policyCause,
        public ?ClassificationFailedException $classifierCause,
        public array $attempts,
        public array $diagnostics,
        public ExecutionSummary $summary,
    );
    public function problem(): ?Problem;
}
  • problem() شیء Problem پنهان‌سازی‌شده برای این پایان، یا null وقتی چیزی برای گزارش Reqtide وجود ندارد.

CompletionDisposition

اینکه یک عملیات چطور پایان یافت.

PHP
enum CompletionDisposition: string {
    case Succeeded = 'succeeded';
    case Failed = 'failed';
    case Rejected = 'rejected';
    case Deferred = 'deferred';
    case Cancelled = 'cancelled';
    case DeadlineExceeded = 'deadline_exceeded';
    case FallbackSucceeded = 'fallback_succeeded';
    case FallbackFailed = 'fallback_failed';
}

ExecutionSummary

شمارش‌های یک عملیات: ارسال‌ها، تلاش‌های مجدد، نتیجه‌ها، راهکارهای جایگزین، زمان سپری‌شده و اینکه حسابداری کامل است یا نه.

PHP
final readonly class ExecutionSummary {
    public function __construct(
        public OperationId $operationId,
        public ProfileVersion $profileVersion,
        public CompletionDisposition $disposition,
        public int $dispatched,
        public int $admittedNotDispatched,
        public int $retries,
        public int $successfulAttempts,
        public int $failedAttempts,
        public int $neutralAttempts,
        public int $actualValues,
        public int $actualExceptions,
        public int $fallbackExecutions,
        public bool $accountingComplete,
        public int $omittedDiagnostics,
        public ?Duration $elapsed,
        public int $admissionUncertain = 0,
    );
}

AttemptRecord

یک تلاش فیزیکی: نتیجه، طبقه‌بندی و رأی مدارشکن آن.

PHP
final readonly class AttemptRecord {
    public function __construct(
        public AttemptId $attemptId,
        public int $dispatchedAttemptNumber,
        public ActualAttemptDisposition $disposition,
        public Outcome $outcome,
        public ?Duration $elapsed,
        public SettlementOverride $logicalOverride,
        public ?OutcomeClassification $classification,
        public CircuitVerdict $circuitVerdict,
    );
}

Diagnostic

یک یادداشت محدود دربارهٔ یک مرحله و دلیل، مانند retry / attempts_exhausted.

PHP
final readonly class Diagnostic {
    public function __construct(
        public string $stageCode,
        public string $reasonCode,
    );
    public static function of(Stage $stage, ReasonCode $reason): self;
    public function stage(): ?Stage;
    public function reason(): ?ReasonCode;
}

خطاها و دلایل

استثناهای خودتان بدون پوشش بیرون می‌آیند. تصمیم Reqtide یک استثنای نوع‌دار است که ProblemCarrier را پیاده‌سازی می‌کند. بر اساس reason() و problem() شاخه کنید، نه بر اساس متن پیام.

Problem

گزارش تغییرناپذیر و امن از نظر پنهان‌سازی، با الگوی جزئیات مسئلهٔ RFC 9457. فقط از فراداده‌های کد ساخته می‌شود: هیچ پیام، نشانی، هدر یا اعتبارنامه‌ای وارد آن نمی‌شود. نام و ترتیب اعضا بخشی از API است. عبارت‌بندی title و detail این‌طور نیست.

PHP
final readonly class Problem {
    public const TYPE_PREFIX = 'tag:enaloo.com,2026:reqtide:problem:';
    public ?Stage $stage;
    public ?string $correlationId;
    public array $causes;
    public function __construct(
        public ReasonCode $code,
        ?Stage $stage = null,
        public ?OperationId $operationId = null,
        public ?ProfileVersion $profileVersion = null,
        public ?AttemptId $attemptId = null,
        ?string $correlationId = null,
        array $causes = [],
    );
    public function withContext(
        OperationId $operationId,
        ProfileVersion $profileVersion,
        ?AttemptId $attemptId = null,
        ?string $correlationId = null,
    ): self;
    public function type(): string;
    public function title(): string;
    public function category(): Category;
    public function severity(): Severity;
    public function retryability(): Retryability;
    public function detail(): string;
    public function toArray(): array;
    public function jsonSerialize(): array;
}

ProblemCarrier

هر استثنایی که یک تصمیم Reqtide را توصیف می‌کند، این را پیاده‌سازی می‌کند.

PHP
interface ProblemCarrier extends ReqtideException {
    public function reason(): ReasonCode;
    public function problem(): Problem;
}

ReqtideException

نشانگر هر استثنایی که خود Reqtide پرتاب می‌کند. استثناهای خودتان هرگز در آن پیچیده نمی‌شوند.

PHP
interface ReqtideException {
}

ReasonCode

رجیستری کدهای دلیل پایدار. وقتی روی آن match می‌زنید، یک شاخهٔ default نگه دارید: ممکن است موردهای تازه اضافه شود.

PHP
enum ReasonCode: string {
    case CircuitOpen = 'circuit_open';
    case CircuitProbeCapacityExhausted = 'circuit_probe_capacity_exhausted';
    case ConcurrencyCapacityExhausted = 'concurrency_capacity_exhausted';
    case OwnershipLeaseInsufficient = 'ownership_lease_insufficient';
    case CooldownActive = 'cooldown_active';
    case CooldownExceedsDeadline = 'cooldown_exceeds_deadline';
    case RateAccepted = 'rate.accepted';
    case RateCostExceedsCapacity = 'rate.cost_exceeds_capacity';
    case RateExhausted = 'rate.exhausted';
    case RateWaitUnrepresentable = 'rate.wait_unrepresentable';
    case AdmissionRejected = 'admission_rejected';
    case AdmissionDeferred = 'admission_deferred';
    case AdmissionImpossible = 'admission_impossible';
    case CircuitThresholdExceeded = 'circuit.threshold_exceeded';
    case CircuitProbeFailed = 'circuit.probe_failed';
    case CircuitProbesSucceeded = 'circuit.probes_succeeded';
    case CircuitOpenElapsed = 'circuit.open_elapsed';
    case RetryBudgetExhausted = 'retry_budget_exhausted';
    case RetryBudgetCommitRefused = 'retry_budget_commit_refused';
    case AttemptsExhausted = 'attempts_exhausted';
    case OutcomeNotRetryable = 'outcome_not_retryable';
    case RetryDelayExceedsDeadline = 'retry_delay_exceeds_deadline';
    case AttemptAllowanceUnavailable = 'attempt_allowance_unavailable';
    case ReplayContractNotValid = 'replay_contract_not_valid';
    case ReplayHorizonInadequate = 'replay_horizon_inadequate';
    case ReplayHorizonSaturated = 'replay_horizon_saturated';
    case RetryDeadlineReached = 'retry_deadline_reached';
    case RetryCancelled = 'retry_cancelled';
    case RetryAfterExceedsMaximumDelay = 'retry_after_exceeds_maximum_delay';
    case RetryAfterExceedsDeadline = 'retry_after_exceeds_deadline';
    case DelayFailed = 'delay_failed';
    case OperationCancelled = 'operation_cancelled';
    case DeadlineExceeded = 'deadline_exceeded';
    case StateUnavailable = 'unavailable';
    case StateCorrupt = 'corrupt';
    case StateIndeterminate = 'indeterminate';
    case StateCapacityExceeded = 'capacity_exceeded';
    case ClockFailure = 'clock_failure';
    case UnexpectedBackendFailure = 'unexpected';
    case RuntimeAdapterFailure = 'runtime_adapter_failure';
    case RateConsumeIndeterminate = 'rate_consume_indeterminate';
    case CommitNotConfirmed = 'commit_not_confirmed';
    case ClockUnavailable = 'clock_unavailable';
    case RetryClockUnavailable = 'retry_clock_unavailable';
    case FallbackClockUnavailable = 'fallback_clock_unavailable';
    case TimingUnavailable = 'timing_unavailable';
    case FallbackTimingUnavailable = 'fallback_timing_unavailable';
    case ElapsedUnavailable = 'elapsed_unavailable';
    case CancellationSampleFailed = 'cancellation_sample_failed';
    case RandomOutOfRange = 'random_out_of_range';
    case ConcurrencyReleaseFailed = 'concurrency_release_failed';
    case ConcurrencyReleaseStale = 'concurrency_release_stale';
    case CircuitAbandonFailed = 'circuit_abandon_failed';
    case CircuitAbandonStale = 'circuit_abandon_stale';
    case CircuitRecordFailed = 'circuit_record_failed';
    case CircuitRecordStale = 'circuit_record_stale';
    case RetryReservationReleaseFailed = 'retry_reservation_release_failed';
    case CooldownExtendFailed = 'cooldown_extend_failed';
    case CooldownExtensionCapped = 'cooldown_extension_capped';
    case SettlementAccounting = 'settlement_accounting';
    case CompletionSinkFailed = 'completion_sink_failed';
    case EventSinkFailed = 'event_sink_failed';
    case ClassifierFailed = 'classifier_failed';
    case LateSignalExtractionFailed = 'late_signal_extraction_failed';
    case FallbackFailed = 'fallback_failed';
    case DiscardFailed = 'discard_failed';
    case ValueAccepted = 'value_accepted';
    case ValueUnacceptable = 'value_unacceptable';
    case ExceptionRetryable = 'exception_retryable';
    case ExceptionFailure = 'exception_failure';
    case ExceptionIgnored = 'exception_ignored';
    case PreparationFailed = 'preparation_failed';
    case LifecycleFailure = 'lifecycle_failure';
    case UnexpectedFailure = 'unexpected_failure';
    case InvalidConfiguration = 'invalid_configuration';
    case CapabilityMismatch = 'capability_mismatch';
    public function category(): Category;
    public function severity(): Severity;
    public function retryability(): Retryability;
    public function stage(): ?Stage;
    public function title(): string;
}

Retryability

اینکه فراخواننده با یک تصمیم چه کند: صبر کند، دوباره تلاش کند، راه‌اندازی را درست کند یا تطبیق دهد.

PHP
enum Retryability: string {
    case Never = 'never';
    case AfterWait = 'after_wait';
    case Transient = 'transient';
    case Unknown = 'unknown';
}

Category

نوع تصمیمی که یک کد به آن تعلق دارد.

PHP
enum Category: string {
    case Policy = 'policy';
    case Infrastructure = 'infrastructure';
    case Configuration = 'configuration';
    case Classification = 'classification';
    case Fallback = 'fallback';
    case Admission = 'admission';
    case Retry = 'retry';
    case Accounting = 'accounting';
    case Preparation = 'preparation';
}

Severity

شدت راهنما، با نام سطح‌های PSR-3 به‌صورت رشتهٔ ساده.

PHP
enum Severity: string {
    case Debug = 'debug';
    case Info = 'info';
    case Notice = 'notice';
    case Warning = 'warning';
    case Error = 'error';
    case Critical = 'critical';
    public function psr3Level(): string;
    public function rank(): int;
    public function isAtLeast(self $threshold): bool;
}

Stage

مرحلهٔ چرخهٔ حیاتی که یک عیب‌یابی یا مسئله در آن گزارش می‌شود. فقط افزایشی است.

PHP
enum Stage: string {
    case Preflight = 'preflight';
    case Preparation = 'preparation';
    case RetryBudget = 'retry_budget';
    case Admission = 'admission';
    case Barrier = 'barrier';
    case Dispatch = 'dispatch';
    case Settlement = 'settlement';
    case Classification = 'classification';
    case Finalize = 'finalize';
    case Cleanup = 'cleanup';
    case Discard = 'discard';
    case Retry = 'retry';
    case Fallback = 'fallback';
    case Observation = 'observation';
    case Summary = 'summary';
}

PolicyTerminationException

پایهٔ استثناهایی که با آن‌ها یک سیاست عملیات را پایان داد.

PHP
abstract class PolicyTerminationException implements ProblemCarrier, ReqtideException {
    public function problem(): Problem;
}

AdmissionRejectedException

مدارشکن، سقف اجرای هم‌زمان (Bulkhead) یا محدودیت نرخ فراخوانی را رد کرد. callable شما اجرا نشد.

PHP
final class AdmissionRejectedException extends PolicyTerminationException {
    public function __construct(
        public readonly AdmissionDecision $decision,
        ?Throwable $previous = null,
    );
    public function reason(): ReasonCode;
}

AdmissionDeferredException

ردی که انتظار مثبتی همراه دارد، مثلاً دورهٔ انتظار یا یک Retry-After که نمی‌شود به آن عمل کرد.

PHP
final class AdmissionDeferredException extends PolicyTerminationException {
    public function __construct(
        public readonly AdmissionDecision $decision,
        ?Throwable $previous = null,
    );
    public function reason(): ReasonCode;
}

ImpossibleAdmissionException

درخواست هرگز پذیرفته نخواهد شد، مثلاً هزینهٔ نرخ بالاتر از ظرفیت است.

PHP
final class ImpossibleAdmissionException extends PolicyTerminationException {
    public function __construct(
        public readonly AdmissionDecision $decision,
        ?Throwable $previous = null,
    );
    public function reason(): ReasonCode;
}

DeadlineExceededException

مهلت کل گذشت. مقدار دیرهنگام با این استثنا جایگزین می‌شود.

PHP
final class DeadlineExceededException extends PolicyTerminationException {
    public function reason(): ReasonCode;
}

OperationCancelledException

عملیات از طریق لغو خودش لغو شد.

PHP
final class OperationCancelledException extends PolicyTerminationException {
    public function reason(): ReasonCode;
}

FallbackFailedException

خود راهکار جایگزین استثنا پرتاب کرد. getPrevious() استثنای راهکار جایگزین است.

PHP
final class FallbackFailedException implements ProblemCarrier, ReqtideException {
    public function __construct(
        public readonly Outcome $originalOutcome,
        public readonly Throwable $fallbackCause,
    );
    public function reason(): ReasonCode;
    public function problem(): Problem;
}

InvalidConfigurationException

یک مقدار، گزینه یا ترکیب نامعتبر است. پیش از ارسال هر چیزی پرتاب می‌شود.

PHP
final class InvalidConfigurationException implements ProblemCarrier, ReqtideException {
    public function reason(): ReasonCode;
    public function problem(): Problem;
}

CapabilityMismatchException

رفتار پیکربندی‌شده قابلیتی می‌خواهد که runtime، زمان‌بند یا بک‌اند انتخاب‌شده اعلام نکرده است.

PHP
final class CapabilityMismatchException implements ProblemCarrier, ReqtideException {
    public function reason(): ReasonCode;
    public function problem(): Problem;
}

InfrastructureException

پایهٔ خطاهای ساعت و بک‌اند وضعیت. این خطاها هرگز به‌عنوان موفقیت پنهان نمی‌شوند.

PHP
abstract class InfrastructureException implements ProblemCarrier, ReqtideException {
    public function problem(): Problem;
}

StateUnavailableException

به بک‌اند وضعیت دسترسی پیدا نشد. فراخوانی محافظت‌شده اجرا نمی‌شود.

PHP
final class StateUnavailableException extends InfrastructureException {
    public function reason(): ReasonCode;
}

StateCapacityExceededException

بک‌اند حافظه به سقف خود رسید و پارتیشن تازه را رد کرد.

PHP
final class StateCapacityExceededException extends InfrastructureException {
    public function reason(): ReasonCode;
}

CorruptStateException

بک‌اند وضعیت، وضعیت خراب پیدا کرد.

PHP
final class CorruptStateException extends InfrastructureException {
    public function reason(): ReasonCode;
}

IndeterminateStateException

نتیجهٔ یک عملیات بک‌اند وضعیت نامشخص است.

PHP
final class IndeterminateStateException extends InfrastructureException {
    public function reason(): ReasonCode;
}

ClockFailureException

ساعت خوانده نشد.

PHP
final class ClockFailureException extends InfrastructureException {
    public function reason(): ReasonCode;
}

ClassificationFailedException

خود طبقه‌بند استثنا پرتاب کرد.

PHP
final class ClassificationFailedException implements ProblemCarrier, ReqtideException {
    public function __construct(
        public readonly Outcome $actualOutcome,
        public readonly Throwable $classifierCause,
    );
    public function reason(): ReasonCode;
    public function problem(): Problem;
}

PreparationFailedException

آماده‌سازی تلاش یا راستی‌آزمایی تکرار ناموفق بود. هیچ چیز ارسال نشد.

PHP
final class PreparationFailedException implements ProblemCarrier, ReqtideException {
    public function __construct(public readonly Throwable $preparationCause);
    public function reason(): ReasonCode;
    public function problem(): Problem;
}

رویدادها

هسته رویدادهای نوع‌دار خودش را منتشر می‌کند و به هیچ کتابخانهٔ تله‌متری وابسته نیست. یک EventSink به compileInMemory() بدهید. sink خراب هرگز نتیجهٔ شما را جایگزین نمی‌کند.

EventSink

همهٔ رویدادها را دریافت می‌کند. برای ثبت لاگ یا شمارش آن را پیاده‌سازی کنید.

PHP
interface EventSink {
    public function emit(Event $event): void;
}

Event

قرارداد پایهٔ همهٔ رویدادها: هر کدام عملیات و نسخهٔ پروفایل خود را نام می‌برد. EventSeverity::of() به رویداد یک شدت می‌دهد.

PHP
interface Event {
    public function operationId(): OperationId;
    public function profileVersion(): ProfileVersion;
}

RetryScheduled

یک تلاش مجدد پس از یک تأخیر زمان‌بندی شد.

PHP
final readonly class RetryScheduled implements Event {
    public function __construct(
        private OperationId $operation,
        private ProfileVersion $profile,
        public int $nextDispatchedAttemptNumber,
        public Duration $delay,
        public string $reasonCode,
    );
    public function operationId(): OperationId;
    public function profileVersion(): ProfileVersion;
}

AdmissionRejected

یک سیاست تلاشی را رد کرد. policyKind و reasonCode می‌گویند کدام.

PHP
final readonly class AdmissionRejected implements Event {
    public function __construct(
        private OperationId $operation,
        private ProfileVersion $profile,
        public string $policyKind,
        public string $reasonCode,
    );
    public function operationId(): OperationId;
    public function profileVersion(): ProfileVersion;
    public function reason(): ?ReasonCode;
    public function severity(): Severity;
}

AttemptCompleted

یک تلاش تعیین تکلیف شد، همراه با رأی مدارشکن آن.

PHP
final readonly class AttemptCompleted implements Event {
    public function __construct(
        private OperationId $operation,
        private ProfileVersion $profile,
        public AttemptId $attemptId,
        public CircuitVerdict $verdict,
        public ?Duration $elapsed,
    );
    public function operationId(): OperationId;
    public function profileVersion(): ProfileVersion;
}

OperationCompleted

عملیات پایان یافت، همراه با وضعیت پایان آن.

PHP
final readonly class OperationCompleted implements Event {
    public function __construct(
        private OperationId $operation,
        private ProfileVersion $profile,
        public CompletionDisposition $disposition,
        public ?Duration $elapsed,
        public bool $accountingComplete,
    );
    public function operationId(): OperationId;
    public function profileVersion(): ProfileVersion;
}

CircuitTransitioned

مدار تغییر وضعیت داد.

PHP
final readonly class CircuitTransitioned implements Event {
    public function __construct(
        private OperationId $operation,
        private ProfileVersion $profile,
        public string $fromState,
        public string $toState,
        public string $reasonCode,
    );
    public function operationId(): OperationId;
    public function profileVersion(): ProfileVersion;
    public function reason(): ?ReasonCode;
    public function severity(): Severity;
}

BackendErrorObserved

یک بک‌اند وضعیت خطا گزارش کرد.

PHP
final readonly class BackendErrorObserved implements Event {
    public function __construct(
        private OperationId $operation,
        private ProfileVersion $profile,
        public string $backendKind,
        public string $failureCode,
    );
    public function operationId(): OperationId;
    public function profileVersion(): ProfileVersion;
    public function reason(): ?ReasonCode;
    public function severity(): Severity;
}

AccountingDegraded

یک مرحلهٔ حسابداری پس از تماس شکست خورد یا کهنه بود. reasonCode می‌گوید کدام.

PHP
final readonly class AccountingDegraded implements Event {
    public function __construct(
        private OperationId $operation,
        private ProfileVersion $profile,
        public string $reasonCode,
    );
    public function operationId(): OperationId;
    public function profileVersion(): ProfileVersion;
    public function reason(): ?ReasonCode;
    public function severity(): Severity;
}

NullEventSink

گیرندهٔ (sink) پیش‌فرض: همهٔ رویدادها را دور می‌ریزد.

PHP
final class NullEventSink implements EventSink {
    public function emit(Event $event): void;
}

EventSeverity

شدت یک رویداد، با نام سطح‌های PSR-3.

PHP
final class EventSeverity {
    public static function of(Event $event): Severity;
    public static function ofDisposition(
        CompletionDisposition $disposition,
    ): Severity;
}

ابزارهای آزمون

در فضای نام Enaxon\Reqtide\Testing و در همان بسته عرضه می‌شود. فقط برای آزمون است: هرگز از کد تولید صدایشان نزنید. راهنمای آزمون با ساعت مجازی را ببینید.

VirtualClock

ساعتی که فقط وقتی جلو می‌رود که شما جلو ببرید. از یک تاریخ ثابت شروع می‌شود تا آزمون هر روز همان پاسخ را بدهد.

PHP
final class VirtualClock implements Clock {
    public const DEFAULT_WALL_START = '2026-01-01T00:00:00+00:00';
    public function __construct(
        int $initialMonotonicNanoseconds = 1000000000,
        ?DateTimeImmutable $initialWall = null,
    );
    public function startingAt(DateTimeImmutable $wall): self;
    public function monotonicNow(): int;
    public function wallNow(): DateTimeImmutable;
    public function advance(Duration $duration): void;
    public function advanceMonotonicOnly(Duration $duration): void;
    public function setMonotonic(int $nanoseconds): void;
    public function setWall(DateTimeImmutable $wall): void;
    public function failNextMonotonicReads(int $count = 1): void;
    public function failNextWallReads(int $count = 1): void;
    public function monotonicReadCount(): int;
    public function wallReadCount(): int;
    public function peekMonotonic(): int;
}

VirtualDelayScheduler

به‌جای خوابیدن، یک VirtualClock را جلو می‌برد و هر تأخیر درخواست‌شده را ثبت می‌کند.

PHP
final class VirtualDelayScheduler implements DelayScheduler {
    public function __construct(private readonly VirtualClock $clock);
    public function capability(): SchedulingCapability;
    public function cancelDuringNextDelay(
        CancellationToken $token,
        Duration $after,
    ): void;
    public function delay(
        Duration $duration,
        Deadline $deadline,
        Cancellation $cancellation,
    ): DelayDisposition;
    public function records(): array;
    public function requestedDelays(): array;
    public function callCount(): int;
    public function totalElapsed(): Duration;
}

ControlledRuntimeAdapter

زمان اجرای (runtime) همگامی که با اسکریپت هدایت می‌شود: در هر ارسال یک مقدار برگردانید، استثنا پرتاب کنید، ساعت را جلو ببرید یا لغو را درخواست کنید.

PHP
final class ControlledRuntimeAdapter implements RuntimeAdapter {
    public function __construct(
        private readonly VirtualClock $clock,
        private readonly ?DispatchScript $default = null,
        private readonly ?RuntimeCapabilities $capabilities = null,
    );
    public static function defaultCapabilities(): RuntimeCapabilities;
    public function enqueue(DispatchScript ...$scripts): void;
    public function capabilities(): RuntimeCapabilities;
    public function invoke(
        PreparedAttempt $operation,
        AttemptContext $context,
        AttemptControls $controls,
    ): RuntimeExecution;
    public function dispatchCount(): int;
    public function dispatches(): array;
    public function attemptContexts(): array;
    public function pendingScripts(): int;
}

DispatchScript

یک ارسال اسکریپت‌شده.

PHP
final readonly class DispatchScript {
    public static function returning(mixed $value): self;
    public static function throwing(Throwable $exception): self;
    public static function callingOperation(): self;
    public function advancing(Duration $duration): self;
    public function requestingCancellation(CancellationToken $token): self;
}

RecordingEventSink

همهٔ رویدادها را برای بررسی در آزمون نگه می‌دارد.

PHP
final class RecordingEventSink implements EventSink {
    public function emit(Event $event): void;
    public function throwOnEmit(Throwable $failure, ?int $times = null): void;
    public function stopThrowing(): void;
    public function events(): array;
    public function ofType(string $class): array;
    public function count(): int;
    public function clear(): void;
}

SeededRandomSource

تصادفی‌سازی با seed: seed یکسان، دنبالهٔ یکسان.

PHP
final class SeededRandomSource implements RandomSource {
    public function __construct(public readonly int $seed);
    public function integer(int $minimumInclusive, int $maximumInclusive): int;
    public function draws(): int;
}

ScriptedRandomSource

فهرستی صف‌شده از عددهای صحیح برمی‌گرداند و وقتی تمام شود، با صدای بلند شکست می‌خورد.

PHP
final class ScriptedRandomSource implements RandomSource {
    public function __construct(array $values);
    public function enqueue(int ...$values): void;
    public function integer(int $minimumInclusive, int $maximumInclusive): int;
    public function remaining(): int;
    public function requests(): array;
}

بستهٔ Redis: راه‌اندازی حالت مشترک

این کلاس‌ها به بستهٔ جداگانهٔ enaxon/reqtide-redis و فضای نام Enaxon\Reqtide\Redis تعلق دارند. این بسته جداگانه نصب می‌شود. راهنمای حالت مشترک با Redis را ببینید. میزبان رجیستری و کاربران ACL را می‌سازد. برنامه فقط environment را می‌سازد.

RedisEnvironment

همتای حالت مشترک InMemoryEnvironment. یک RuntimeEnvironment می‌سازد که سیاست‌هایش در یک رجیستری Redis زندگی می‌کنند، دقیقاً برای سیاست‌هایی که تعریف پیکربندی کرده است. ساخت آن هیچ اتصالی باز نمی‌کند.

PHP
final class RedisEnvironment {
    public static function for(
        PipelineDefinition $definition,
        OutcomeClassifier $classifier,
        RedisConnectionOptions $connection,
        RedisRegistry $registry,
        ?EventSink $events = null,
    ): RuntimeEnvironment;
    public static function explain(
        CompiledPipeline $pipeline,
        RedisConnectionOptions $connection,
        RedisRegistry $registry,
    ): PipelineExplanation;
}
  • for() محیط (environment) را برمی‌گرداند تا به PipelineBuilder::compile() بدهید. ساعت هر تصمیم، ساعت سرور Redis است.
  • explain() واقعیت‌های حالت مشترک را به توضیح معمول اضافه می‌کند: دامنهٔ وضعیت، مهلت I/O، TLS، هویت رجیستری و سقف‌ها. بدون I/O، و بدون میزبان، گذرواژه، پیشوند یا رازی در خروجی.

RedisRegistry

هویت تغییرناپذیر یک رجیستری، واحد جداسازی حالت مشترک: یک پیشوند کلید، یک هویت، دو سقف و یک راز با طول 32 بایت یا بیشتر. این شیء چیزی در Redis نمی‌سازد.

PHP
final readonly class RedisRegistry {
    public const SCHEMA_VERSION = 1;
    public const DEFAULT_MAX_PARTITIONS = 10000;
    public const DEFAULT_MAX_RECORDS = 20000;
    public function __construct(
        public string $keyPrefix,
        public string $identity,
        private string $secret,
        public int $maxPartitions = self::DEFAULT_MAX_PARTITIONS,
        public int $maxRecords = self::DEFAULT_MAX_RECORDS,
    );
}

RedisRegistryAdmin

تنها راه ساختن، بررسی یا بازنشسته کردن یک رجیستری. میزبان آن را با اتصال مدیریتی خودش صدا می‌زند. برنامه هرگز.

PHP
final class RedisRegistryAdmin {
    public function __construct(
        RedisConnectionOptions $administrativeConnection,
        private readonly RedisRegistry $registry,
    );
    public function initialize(): RegistryStatus;
    public function verify(): RegistryStatus;
    public function retire(): RegistryStatus;
    public function purgeRetired(): int;
    public function inspectServer(): ServerPolicyReport;
}
  • initialize() رجیستری را می‌سازد، یا یک رجیستری یکسان را تأیید می‌کند. هویت یا سقف‌های متفاوت رد می‌شوند. روی سروری قدیمی‌تر از Redis 7.0 و روی پیشوندی که هنوز بازمانده‌های یک رجیستری بازنشسته را دارد، رد می‌شود.
  • verify() وجود، هویت، طرح‌واره و شمارنده‌ها را بررسی می‌کند. چیزی نمی‌نویسد.
  • retire() فراداده‌های رجیستری را حذف می‌کند. کلیدهای پارتیشن و رکورد می‌مانند تا purgeRetired() آن‌ها را پاک کند.
  • purgeRetired() کلیدهایی را که یک رجیستری بازنشسته بر جا گذاشته پاک می‌کند. تا وقتی رجیستری وجود دارد، اجرا نمی‌شود. تعداد کلیدهای پاک‌شده را برمی‌گرداند.
  • inspectServer() مقدار maxmemory-policy و maxmemory را می‌خواند. به CONFIG GET و INFO نیاز دارد. سرور قدیمی‌تر از Redis 7.0 را رد می‌کند.

RedisConnectionOptions

گزینه‌های تغییرناپذیر برای یک اتصال مستقیم Redis. هر دو مهلت الزامی است. گزینهٔ تلاش مجدد وجود ندارد و راهی برای خاموش کردن بررسی گواهی یا نام میزبان نیست. گذرواژه هرگز در var_dump یا پیام استثنا ظاهر نمی‌شود.

PHP
final readonly class RedisConnectionOptions {
    public function __construct(
        public string $host,
        public float $connectTimeoutSeconds,
        public float $readWriteTimeoutSeconds,
        public int $port = 6379,
        public ?string $username = null,
        private ?string $password = null,
        public bool $tls = false,
        public ?string $caFile = null,
        public ?string $tlsServerName = null,
    );
}

RedisAcl

قاعده‌های ACL در Redis که کتابخانه لازم دارد، نه بیشتر. آن‌ها را چاپ کنید و به ACL SETUSER بدهید.

PHP
final class RedisAcl {
    public static function execution(RedisRegistry $registry): array;
    public static function administration(RedisRegistry $registry): array;
}
  • execution() قاعده‌های کاربر برنامه: اسکریپت‌های عرضه‌شده و فرمان‌هایشان، فقط روی کلیدهای زیر پیشوند رجیستری.
  • administration() همان قاعده‌ها به‌اضافهٔ SCAN، UNLINK، CONFIG GET و INFO، برای میزبان.

RegistryStatus

آنچه یک فراخوانی مدیریت رجیستری پیدا کرد یا انجام داد: اینکه رجیستری را ساخت یا نه، نشانهٔ اختیار (authority watermark)، و شمارش‌ها در برابر سقف‌ها.

PHP
final readonly class RegistryStatus {
    public function __construct(
        public bool $created,
        public int $watermarkSeconds,
        public int $watermarkMicroseconds,
        public int $partitions,
        public int $records,
        public int $maxPartitions,
        public int $maxRecords,
    );
}

ServerPolicyReport

کاری که سرور هنگام تمام شدن حافظه می‌کند. متد protectsState() برای noeviction یا نبود سقف حافظه true است، برای سیاستی که می‌تواند کلیدها را حذف کند false، و وقتی سیاست خوانده نشد null.

PHP
final readonly class ServerPolicyReport {
    public function __construct(
        public ?string $evictionPolicy,
        public ?int $maxMemoryBytes,
    );
    public function protectsState(): ?bool;
}

بستهٔ Redis: بهره‌برداری

این‌ها را از یک worker، یک زمان‌بند یا یک فرمان اپراتور اجرا کنید، با اتصالی که قاعده‌های مدیریتی دارد. کتابخانه هرگز خودش آن‌ها را صدا نمی‌زند.

RedisRegistryMaintenance

پاک‌سازی محدود یک رجیستری. هر گام حداکثر 128 نامزد و حداکثر 128 رکورد تمام‌شده را بررسی می‌کند. هیچ چیز آن را برای شما اجرا نمی‌کند.

PHP
final class RedisRegistryMaintenance {
    public function __construct(
        RedisConnectionOptions $connection,
        private readonly RedisRegistry $registry,
        ?RedisBridge $bridge = null,
    );
    public function step(): array;
}
  • step() یک گام اجرا می‌کند و برمی‌گرداند چه چیزی حذف شد و آیا more ممکن است پیدا شود. تا وقتی more برابر false نشده، دوباره صدا بزنید.

RedisCircuitAdmin

اقدام‌های اپراتور روی پارتیشن‌های مدارشکن. کتابخانه هرگز reset را صدا نمی‌زند.

PHP
final class RedisCircuitAdmin {
    public function __construct(
        RedisConnectionOptions $connection,
        private readonly RedisRegistry $registry,
        ?RedisBridge $bridge = null,
    );
    public function reset(PolicyIdentity $identity): ?Generation;
}
  • reset() مدار را می‌بندد، تاریخچه‌اش را دور می‌ریزد و هر مجوز فعال را کهنه می‌کند. نسل تازه را برمی‌گرداند، یا اگر پارتیشن وجود نداشته باشد null.

بستهٔ Redis: بک‌اندها

برای هر سیاست یک بک‌اند. RedisEnvironment::for() آن‌ها را برایتان می‌سازد. فقط وقتی خودتان یکی بسازید که بخواهید آن را به ReqtideClient::withBackends() بدهید. آرگومان سوم سازنده برای آزمون‌هاست: آن را نگذارید. هر بک‌اند برای هر گام یک فراخوانی اسکریپت سمت سرور می‌فرستد و هیچ فرمانی دو بار فرستاده نمی‌شود.

RedisRateLimitBackend

سطل توکن، پنجرهٔ ثابت و شمارندهٔ لغزان مشترک.

PHP
final class RedisRateLimitBackend implements RateLimitBackend, StateBackend {
    public function __construct(
        RedisConnectionOptions $connection,
        private readonly RedisRegistry $registry,
        ?RedisBridge $bridge = null,
    );
    public function capabilities(): StateBackendCapabilities;
    public function consume(
        RateLimitPolicy $policy,
        PositiveInt $cost,
        CommandId $command,
    ): AdmissionDecision;
    public function inspect(
        RateLimitPolicy $policy,
        PositiveInt $requestedCost,
    ): RateLimitInspection;
}

RedisCircuitBackend

مدارشکن مشترک. وضعیت باز و نیمه‌باز، مجوزهای فعال و تاریخچهٔ شمارش هرگز بازیابی یا حذف نمی‌شوند.

PHP
final class RedisCircuitBackend implements CircuitBackend, StateBackend {
    public function __construct(
        RedisConnectionOptions $connection,
        private readonly RedisRegistry $registry,
        ?RedisBridge $bridge = null,
    );
    public function capabilities(): StateBackendCapabilities;
    public function acquire(
        CircuitPolicy $policy,
        AttemptId $attempt,
        PermitOwnerId $owner,
        CommandId $command,
    ): CircuitAdmission;
    public function record(
        CircuitPolicy $policy,
        CircuitPermit $permit,
        CircuitVerdict $verdict,
        CommandId $command,
    ): FinalizationResult;
    public function abandon(
        CircuitPolicy $policy,
        CircuitPermit $permit,
        CommandId $command,
    ): FinalizationResult;
}

RedisConcurrencyBackend

سقف اجرای هم‌زمان (Bulkhead) مشترک با اجاره (lease). صاحبان فعال هرگز حذف نمی‌شوند.

PHP
final class RedisConcurrencyBackend implements ConcurrencyBackend, StateBackend {
    public function __construct(
        RedisConnectionOptions $connection,
        private readonly RedisRegistry $registry,
        ?RedisBridge $bridge = null,
    );
    public function capabilities(): StateBackendCapabilities;
    public function acquire(
        ConcurrencyPolicy $policy,
        PermitOwnerId $owner,
        CommandId $command,
    ): ConcurrencyAdmission;
    public function release(
        ConcurrencyPolicy $policy,
        ConcurrencyPermit $permit,
        CommandId $command,
    ): FinalizationResult;
}

RedisRetryBudgetBackend

سهمیهٔ تلاش مجدد مشترک. موجودی هرگز بازیابی یا حذف نمی‌شود.

PHP
final class RedisRetryBudgetBackend implements RetryBudgetBackend, StateBackend {
    public function __construct(
        RedisConnectionOptions $connection,
        private readonly RedisRegistry $registry,
        ?RedisBridge $bridge = null,
    );
    public function capabilities(): StateBackendCapabilities;
    public function inspect(RetryBudgetPolicy $policy): RetryBudgetInspection;
    public function reserve(
        RetryBudgetPolicy $policy,
        AttemptId $attempt,
        PermitOwnerId $owner,
        CommandId $command,
    ): RetryReservationDecision;
    public function commit(
        RetryBudgetPolicy $policy,
        RetryBudgetReservation $reservation,
        CommandId $command,
    ): RetryBudgetFinalizationResult;
    public function release(
        RetryBudgetPolicy $policy,
        RetryBudgetReservation $reservation,
        CommandId $command,
    ): RetryBudgetFinalizationResult;
}

RedisCooldownBackend

دورهٔ انتظار مشترک. تمدید هرگز وقفهٔ موجود را کوتاه نمی‌کند.

PHP
final class RedisCooldownBackend implements CooldownBackend, StateBackend {
    public function __construct(
        RedisConnectionOptions $connection,
        private readonly RedisRegistry $registry,
        ?RedisBridge $bridge = null,
    );
    public function capabilities(): StateBackendCapabilities;
    public function inspect(CooldownPolicy $policy): CooldownDecision;
    public function extend(
        CooldownPolicy $policy,
        Duration $extension,
        CommandId $command,
    ): CooldownDecision;
}

بستهٔ Guzzle

این کلاس‌ها به بستهٔ جداگانهٔ enaxon/reqtide-guzzle و فضای نام Enaxon\Reqtide\Guzzle تعلق دارند. این بسته جداگانه نصب می‌شود. راهنمای درخواست‌های Guzzle با Reqtide را ببینید. وضعیت 4xx یا 5xx یک پاسخ است، نه استثنا.

ReqtideClient

نقطهٔ ورود. handlerهای cURL خودش را در اختیار دارد و هر عملیات را، با همهٔ تلاش‌هایش، از یک پایپ‌لاین کامپایل‌شده اجرا می‌کند.

PHP
final class ReqtideClient {
    public static function inMemory(
        PipelineBuilder $pipeline,
        ?GuzzleConfiguration $configuration = null,
        ?EventSink $events = null,
    ): self;
    public static function withBackends(
        PipelineBuilder $pipeline,
        ?RateLimitBackend $rateLimit = null,
        ?CircuitBackend $circuit = null,
        ?ConcurrencyBackend $concurrency = null,
        ?RetryBudgetBackend $retryBudget = null,
        ?CooldownBackend $cooldown = null,
        ?GuzzleConfiguration $configuration = null,
        ?EventSink $events = null,
    ): self;
    public function uri(UriInterface|string $reference): UriInterface;
    public function send(
        HttpOperation $operation,
        Duration $timeout,
        ?Cancellation $cancellation = null,
    ): ResponseInterface;
    public function sendDetailed(
        HttpOperation $operation,
        Duration $timeout,
        ?Cancellation $cancellation = null,
    ): ExecutionCompletion;
    public function sendAsync(
        HttpOperation $operation,
        Duration $timeout,
        ?Cancellation $cancellation = null,
    ): PromiseInterface;
    public function explain(bool $async = false): PipelineExplanation;
}
  • inMemory() یک کلاینت با وضعیت محلی فرایند.
  • withBackends() کلاینتی که وضعیتش در بک‌اندهایی است که می‌دهید، مثلاً بک‌اندهای Redis. برای هر سیاستی که پایپ‌لاین پیکربندی می‌کند، یک بک‌اند بدهید.
  • uri() یک ارجاع را نسبت به نشانی پایه حل می‌کند (RFC 3986). نشانی پایه مرز امنیتی نیست: ارجاع مطلق، میزبان را عوض می‌کند.
  • send() عملیات را اجرا می‌کند و پاسخ را برمی‌گرداند، یا شکست عملیات را پرتاب می‌کند. مهلت همهٔ تلاش‌ها و همهٔ انتظارها را پوشش می‌دهد.
  • sendDetailed() به‌جای پرتاب، یک ExecutionCompletion با خلاصهٔ تلاش‌ها و تصمیم‌ها برمی‌گرداند.
  • sendAsync() یک promise تنبل برمی‌گرداند. عملیات وقتی اجرا می‌شود که wait() را صدا بزنید، هر بار یک عملیات.
  • explain() پایپ‌لاین کامپایل‌شدهٔ runtime همگام را توصیف می‌کند، یا با true پایپ‌لاین runtime مبتنی بر promise را. بدون انتقال و بدون تغییر وضعیت.

GuzzleConfiguration

گزینه‌های کلاینت: طبقه‌بند، یک فهرست کوتاه از پیش‌فرض‌های کلاینت Guzzle و یک نشانی پایهٔ اختیاری. هر پیش‌فرض دیگر کلاینت با نام رد می‌شود.

PHP
final readonly class GuzzleConfiguration {
    public const ALLOWED_CLIENT_DEFAULTS = array (
  0 => 'headers',
  1 => 'auth',
  2 => 'proxy',
  3 => 'verify',
  4 => 'cert',
  5 => 'ssl_key',
  6 => 'crypto_method',
  7 => 'force_ip_resolve',
  8 => 'version',
  9 => 'decode_content',
);
    public HttpOutcomeClassifier $classifier;
    public ?UriInterface $baseUri;
    public function __construct(
        ?HttpOutcomeClassifier $classifier = null,
        public array $clientDefaults = [],
        UriInterface|string|null $baseUri = null,
        public array $credentialHeaders = [],
    );
}

HttpOperation

یک عملیات HTTP منطقی: یک درخواست مطلق و اعلام صریح شما دربارهٔ اینکه آیا و چطور می‌شود آن را دوباره فرستاد. چیزی از روی متد یا هدر حدس زده نمی‌شود.

PHP
final readonly class HttpOperation {
    public const DEFAULT_MAX_VERIFIED_BODY_BYTES = 16777216;
    public ?Closure $bodyFactory;
    public function forClient(GuzzleConfiguration $configuration): self;
    public static function read(
        RequestInterface $request,
        string $operationGroup,
        Duration $validFor,
        array $retryableOutcomeCodes = [],
        ?Closure $bodyFactory = null,
        ?Clock $clock = null,
        ?string $credentialKey = null,
        BodyIntegrity $bodyIntegrity = BodyIntegrity::Verified,
        int $maxVerifiedBodyBytes = self::DEFAULT_MAX_VERIFIED_BODY_BYTES,
    ): self;
    public static function idempotentMutation(
        RequestInterface $request,
        string $operationGroup,
        string $identityValue,
        string $identityScope,
        string $duplicateHandling,
        Duration $validFor,
        ?Duration $retention = null,
        ?string $identityHeader = 'Idempotency-Key',
        array $retryableOutcomeCodes = [],
        ?Closure $bodyFactory = null,
        ?Clock $clock = null,
        ?string $credentialKey = null,
        BodyIntegrity $bodyIntegrity = BodyIntegrity::Verified,
        int $maxVerifiedBodyBytes = self::DEFAULT_MAX_VERIFIED_BODY_BYTES,
    ): self;
    public static function single(
        RequestInterface $request,
        string $operationGroup,
        ?string $credentialKey = null,
    ): self;
    public function metadata(): OperationMetadata;
}
  • read() برای GET و HEAD. اعلام می‌کنید که تکرار درخواست اثر جانبی ندارد، تا چه مدت، و کدام نتیجه‌ها را می‌شود دوباره تلاش کرد.
  • idempotentMutation() برای POST، PUT، PATCH یا DELETE که سرور آن را بر اساس یک هویت حذف تکرار می‌کند. در هر تلاش همان بدنه و همان هویت فرستاده می‌شود و هویت پیش از هر تلاش بررسی می‌شود.
  • single() یک بار فرستاده می‌شود و هرگز تکرار نمی‌شود. هسته آن را در پایپ‌لاینی که بیش از یک بار تلاش مجدد می‌کند، رد می‌کند.
  • metadata() واقعیت‌های محدودی که به پایپ‌لاین داده می‌شود: اعلام ایمنی و ویژگی‌های توصیف‌گر.

HttpOutcomeClassifier

تعیین می‌کند کدام وضعیت‌ها و خطاهای cURL دوباره تلاش می‌شوند، به حساب مدارشکن می‌آیند، می‌توانند به راهکار جایگزین برسند یا دورهٔ انتظار را تنظیم می‌کنند. هر متد یک نمونهٔ تازه برمی‌گرداند.

PHP
final readonly class HttpOutcomeClassifier implements OutcomeClassifier {
    public static function starter(?Clock $clock = null): self;
    public static function empty(?Clock $clock = null): self;
    public function withRetryableStatuses(int ...$statuses): self;
    public function withCircuitFailureStatuses(int ...$statuses): self;
    public function withCircuitNeutralStatuses(int ...$statuses): self;
    public function withFallbackStatuses(int ...$statuses): self;
    public function withRetryAfterStatuses(int ...$statuses): self;
    public function withRetryableTransportErrnos(int ...$errnos): self;
    public function retryableOutcomeCodes(): array;
    public function classify(
        Outcome $outcome,
        OperationMetadata $metadata,
    ): OutcomeClassification;
}
  • starter() یک مجموعهٔ شروع مستند. توصیه برای هر API نیست.
  • empty() روی هیچ چیز تلاش مجدد یا راهکار جایگزین ندارد و Retry-After نمی‌خواند.
  • retryableOutcomeCodes() کدهای دلیلی که می‌شود دوباره تلاششان کرد. آن‌ها را به read() و idempotentMutation() بدهید. فهرست خالی هرگز تلاش مجدد نمی‌کند.

RetryAfter

خوانندهٔ سخت‌گیر Retry-After: ثانیه یا تاریخ HTTP. مقداری که خوانده نشود، انتظار نمی‌دهد.

PHP
final class RetryAfter {
    public const MAX_SECONDS = 9007199254;
    public static function read(
        array $lines,
        DateTimeImmutable $now,
    ): RetryAfterReading;
}
  • read() خط‌های هدر را نسبت به زمان دیواری داده‌شده می‌خواند. بزرگ‌ترین تأخیر معتبر برنده است.

RetryAfterReading

آنچه خط‌های Retry-After یک پاسخ می‌گویند. تأخیر null یعنی بدون کران پایین، نه صفر.

PHP
final readonly class RetryAfterReading {
    public function __construct(
        public ?Duration $delay,
        public int $validLines,
        public int $rejectedLines,
        public bool $outOfRange,
    );
}