Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Catalog · How the catalog works

Random project

DFResilience

Polly-style resilience pipelines for Delphi 10.3 Rio and later

View on GitHub

Anyone may press Interesting, signed in or not. It helps others find this project.

Member rating

No ratings yet.

Sign in to rate this project.

README

DFResilience

English · Türkçe

Polly-style resilience pipelines for Delphi 10.3 Rio and later.

Website: delphifan.com
Email: adsdelphi@gmail.com


English

A resilience pipeline library. Combine Retry, Timeout, Circuit Breaker, Fallback, Rate Limiter, Concurrency Limiter, and Hedging in one fluent pipeline for REST, SOAP, database, and other remote calls.

Installation

Add the src folder to your project search path:

pascal
uses
  DFResilience;

You can also compile packages/DFResilience.dpk.

Quick start

pascal
TDFResiliencePipeline
  .Create
  .AddRetry(3)
  .AddTimeout(5000)
  .AddCircuitBreaker(5, 30000)
  .Execute(
    procedure
    begin
      CallApi;
    end
  );

Full pipeline

Build once and reuse the pipeline when a strategy keeps state, such as a circuit breaker:

pascal
var
  Pipeline: TDFResiliencePipeline;
  Response: string;
begin
  Pipeline :=
    TDFResiliencePipeline.Create
      .AddRetry(
         TDFRetryOptions.Create
           .MaxAttempts(5)
           .Delay(1000)
           .Backoff(TDFBackoffType.Exponential)
           .UseJitter(True))
      .AddTimeout(10000)
      .AddCircuitBreaker(5, 60000)
      .Build;

  Response := Pipeline.Execute<string>(
    function: string
    begin
      Result := IdHTTP1.Get('https://api.example.com/health');
    end);
end;

Order matters: the first strategy you add is the outermost. AddRetry then AddTimeout means every retry attempt has its own timeout.

Strategies

Strategy What it does Simple API
Retry Retries transient failures .AddRetry(3)
Timeout Raises EDFTimeoutException when the limit is exceeded .AddTimeout(5000)
Circuit Breaker Fails fast after a threshold .AddCircuitBreaker(5, 30000)
Fallback Runs an alternative path on failure .AddFallback(...)
Rate Limiter Caps calls inside a time window .AddRateLimiter(100, 60000)
Concurrency Limiter Caps work running at the same time .AddConcurrencyLimiter(10, 20)
Hedging Starts a parallel attempt if a call is slow .AddHedging(2, 2000)

AddRetry(3) means 3 total attempts (do not confuse this with Polly’s MaxRetryAttempts).

For timeout cancellation, use Context.Token or Context.ThrowIfCancellationRequested inside the callback. If the callback ignores the token, work may continue in the background; the pipeline still raises EDFTimeoutException.

Exceptions

  • EDFTimeoutException
  • EDFBrokenCircuitException (RetryAfterMs)
  • EDFIsolatedCircuitException
  • EDFRateLimitedException (RetryAfterMs)

Retry handles all exceptions except a broken circuit and EAbort. To filter:

pascal
.AddRetry(
  TDFRetryOptions.Create
    .MaxAttempts(5)
    .Handle(TDFPredicateBuilder.Create.Handle(EIdHTTPProtocolException).Build))

Requirements

  • Delphi 10.3 Rio or later
  • RTL (System.Threading, System.SyncObjs, generics)

License

MIT.


Türkçe

Resilience pipeline kütüphanesi. REST, SOAP, veritabanı ve harici servis çağrılarında Retry, Timeout, Circuit Breaker, Fallback, Rate Limiter, Concurrency Limiter ve Hedging stratejilerini tek pipeline içinde birleştirir.

Kurulum

src klasörünü proje search path’ine ekleyin:

pascal
uses
  DFResilience;

İsterseniz packages/DFResilience.dpk paketini de derleyebilirsiniz.

Hızlı kullanım

pascal
TDFResiliencePipeline
  .Create
  .AddRetry(3)
  .AddTimeout(5000)
  .AddCircuitBreaker(5, 30000)
  .Execute(
    procedure
    begin
      CallApi;
    end
  );

Tam pipeline

Circuit breaker gibi durum tutan stratejiler için pipeline’ı bir kez Build edip tekrar kullanın:

pascal
var
  Pipeline: TDFResiliencePipeline;
  Response: string;
begin
  Pipeline :=
    TDFResiliencePipeline.Create
      .AddRetry(
         TDFRetryOptions.Create
           .MaxAttempts(5)
           .Delay(1000)
           .Backoff(TDFBackoffType.Exponential)
           .UseJitter(True))
      .AddTimeout(10000)
      .AddCircuitBreaker(5, 60000)
      .Build;

  Response := Pipeline.Execute<string>(
    function: string
    begin
      Result := IdHTTP1.Get('https://api.example.com/health');
    end);
end;

Sıra önemlidir: ilk eklenen strateji en dıştadır. AddRetry sonra AddTimeout demek, her denemenin kendi timeout’una sahip olması demektir.

Stratejiler

Strateji Ne yapar Basit API
Retry Geçici hatalarda tekrar dener .AddRetry(3)
Timeout Süre aşılınca EDFTimeoutException .AddTimeout(5000)
Circuit Breaker Eşik aşılınca fail-fast .AddCircuitBreaker(5, 30000)
Fallback Hata olursa alternatif yol .AddFallback(...)
Rate Limiter Penceredeki çağrı sayısını kısıtlar .AddRateLimiter(100, 60000)
Concurrency Limiter Aynı anda çalışan iş sayısı .AddConcurrencyLimiter(10, 20)
Hedging Gecikince paralel yedek deneme .AddHedging(2, 2000)

AddRetry(3) toplam 3 deneme demektir (Polly’deki MaxRetryAttempts ile karıştırmayın).

Timeout iptali için callback içinde Context.Token veya Context.ThrowIfCancellationRequested kullanın. Callback token’ı yok sayarsa iş arka planda sürebilir; pipeline yine EDFTimeoutException fırlatır.

İstisnalar

  • EDFTimeoutException
  • EDFBrokenCircuitException (RetryAfterMs)
  • EDFIsolatedCircuitException
  • EDFRateLimitedException (RetryAfterMs)

Retry varsayılan olarak broken-circuit ve EAbort dışındaki exception’ları yakalar. Filtrelemek için:

pascal
.AddRetry(
  TDFRetryOptions.Create
    .MaxAttempts(5)
    .Handle(TDFPredicateBuilder.Create.Handle(EIdHTTPProtocolException).Build))

Gereksinimler

  • Delphi 10.3 Rio veya daha yeni
  • RTL (System.Threading, System.SyncObjs, generics)

Lisans

MIT.