buraksenyurt / DistributedChallenge

Bu repoda aslında asenkron mesaj kuyruklarını hedef alan bir dağıtık sistem problemi oluşturmaya ve bu problemin çözümünü uygulamaya çalışıyorum.
111 stars 8 forks source link

Resilience Middleware Kullanımı için Parametre Yapısı #97

Closed buraksenyurt closed 2 months ago

buraksenyurt commented 3 months ago

Resilience paketi ile yüklenen Middleware fonksiyonlarında devreye girip girmeme durumu ile ilgili parametrik bir tablo yapısına ihtiyaç var. Örneğin, Internal Server Error simülasyonu yapan fonksiyon eğer parametre değeri aktif ise bu işi icra etmeli. Amaç çözüm çalışırken bu tip simülasyonları anahtarlar ile kolayca yönetebilmek.

buraksenyurt commented 2 months ago

Bununla ilgili olarak Resistance Nuget paketinde bir düzenleme yapıldı.

Middleware'de araya girdiğmiz InvokeAsync metodunda IOptionsMonitor soyutlaması üzerinden gelen konfigurasyon bilgisine bakarak fonksiyonun işletip işletilmemesini sağlamamız mümkün. Örneğin aşağıdaki gibi.

public class NetworkFailureBehavior(
    RequestDelegate next
    , NetworkFailureProbability failureProbability
    , IOptionsMonitor<ResistanceFlags> optionsMonitor
    , ILogger<NetworkFailureBehavior> logger)
{
    private readonly RequestDelegate _next = next;
    private readonly Random _random = new();
    private readonly int _failureProbability = (int)failureProbability;
    private readonly ILogger<NetworkFailureBehavior> _logger = logger;
    private readonly IOptionsMonitor<ResistanceFlags> _optionsMonitor = optionsMonitor;
    public async Task InvokeAsync(HttpContext context)
    {
        if (!_optionsMonitor.CurrentValue.NetworkFailureIsActive)
        {
            await _next(context);
            return;
        }

        if (_random.Next(1, 101) <= _failureProbability)
        {
            _logger.LogWarning("Simulated newtwork failure with HTTP 500 code.");
            context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
            await context.Response.WriteAsync("Simulated network failure.");
        }
        else
        {
            await _next(context);
        }
    }
}

Buna göre paketi kullanan runtime uygulamasının appsettings dosyasındaki ResistanceFlags sekmesindeki değerleri, InvokeAsync fonksiyonlarının başında kontrol edip istediğimiz simülasyonun başlatılıp başlatılmamasını sağlayabiliyoruz.

Örneğin, Eval.AuditApi servisindeki appsettings.json şöyle ayarlanabilir.

  "ResistanceFlags": {
    "NetworkFailureIsActive": true,
    "LatencyIsActive": false,
    "ResourceRaceIsActive": false,
    "OutageIsActive": false,
    "DataInconsistencyIsActive": false
  }

Buna göre AuditApi için HTTP 500 Network Failure simülasyonu etkinleşir.

Bununla ilgili değişiklikler Main Branch üzerine de alındı.