CoreVitals 1.0.0
dotnet add package CoreVitals --version 1.0.0
NuGet\Install-Package CoreVitals -Version 1.0.0
<PackageReference Include="CoreVitals" Version="1.0.0" />
<PackageVersion Include="CoreVitals" Version="1.0.0" />
<PackageReference Include="CoreVitals" />
paket add CoreVitals --version 1.0.0
#r "nuget: CoreVitals, 1.0.0"
#:package CoreVitals@1.0.0
#addin nuget:?package=CoreVitals&version=1.0.0
#tool nuget:?package=CoreVitals&version=1.0.0
CoreVitals.Resilience
Eine hochperformante, leichtgewichtige und Dependency-Injection-freundliche Resilience-Bibliothek für .NET, die eine robuste Ausführung von Operationen durch konfigurierbare Retry-Strategien mit exponentiellem Backoff und Jitter ermöglicht.
Funktionsumfang
1. Exponentielles Backoff (Exponential Backoff)
Anstatt einen fehlgeschlagenen Aufruf sofort wiederholt abzufeuern (was den Zielserver bei einer Überlastung nur noch weiter in die Knie zwingen würde), wartet die Bibliothek nach jedem Fehlversuch progressiv länger:
- Die Wartezeit berechnet sich dynamisch anhand der Formel: $Delay = InitialDelay \times (BackoffFactor^{Attempt - 1})$
- Beispiel bei 100ms Initial-Delay und Faktor 2.0: 100ms $\rightarrow$ 200ms $\rightarrow$ 400ms $\rightarrow$ 800ms usw.
- Über die Eigenschaft
MaxDelaylässt sich eine Obergrenze festlegen, damit die Wartezeiten nicht ins Unendliche wachsen.
2. Full Jitter (Verhinderung des "Thundering Herd"-Effekts)
Wenn viele Instanzen eines Services gleichzeitig auf eine ausgefallene Ressource zugreifen und alle denselben statischen Backoff-Algorithmus nutzen, treffen die Wiederholungsversuche alle zur exakt gleichen Zeit auf dem Server ein.
- Full Jitter fügt der Wartezeit ein kontrolliertes Zufallsrauschen hinzu. Die tatsächliche Wartezeit wird zufällig zwischen
0und dem maximal berechneten exponentiellen Delay gestreut. - Dies entzerrt die Last auf APIs und Datenbanken unter Hochlastbedingungen dramatisch.
3. Selektive Fehlerfilterung (ShouldRetry)
Nicht jeder Fehler sollte einen Wiederholungsversuch auslösen. Wenn eine API mit einem 401 Unauthorized oder einer ArgumentException antwortet, wird auch ein erneuter Versuch das Problem nicht lösen.
- Über das Prädikat
ShouldRetrysteuern Sie präzise, bei welchen Exceptions ein Retry sinnvoll ist (z. B. nur beiHttpRequestExceptionoderDbException). OperationCanceledException(Abbruch durch den Nutzer) wird standardmäßig nie wiederholt.
4. Volle Unterstützung für asynchrone Programmierung & Cancellation
- Die gesamte Bibliothek ist voll-asynchron (
async/await) und mitConfigureAwait(false)optimiert. - Jede Methode akzeptiert ein
CancellationToken. Ein Abbruch wird sowohl während der Ausführung Ihrer Methode als auch während der Wartezeit (Delay) sofort berücksichtigt, ohne Threads zu blockieren.
5. Echtzeit-Monitoring & Logging (OnRetry)
- Über den optionalen Callback
OnRetryerhalten Sie vor jeder Wartezeit Zugriff auf die aufgetretene Exception, die aktuelle Versuchsnummer und das exakt berechnete Delay. - Optimal für die Integration in strukturiertes Logging (z. B. Serilog, OpenTelemetry, Application Insights).
6. Plattformkompatibilität & Performance (Multi-Targeting)
- .NET 8.0+: Nutzt modernste und hochperformante APIs wie
Random.Shared(vollkommen allocationsfrei und thread-sicher). - .NET Standard 2.0: Kompatibel mit älteren Plattformen (z. B. .NET Framework). Die Thread-Sicherheit bei der Jitter-Generierung wird ohne Locks durch ein
[ThreadStatic] Randomrealisiert. - Keine externen Abhängigkeiten (außer DI Abstractions), was das NuGet-Paket extrem schlank hält.
Installation
Fügen Sie das Paket zu Ihrem Projekt hinzu:
dotnet add package CoreVitals.Resilience
Verwendung
1. Einfache manuelle Verwendung
Sie können die RetryPolicy direkt erstellen und konfigurieren:
using CoreVitals.Resilience;
// Konfiguration definieren
var options = new RetryOptions
{
MaxRetries = 3,
InitialDelay = TimeSpan.FromMilliseconds(200),
MaxDelay = TimeSpan.FromSeconds(5),
BackoffFactor = 2.0,
UseJitter = true,
// Nur bei transienten Netzwerkfehlern o.Ä. retryen
ShouldRetry = ex => ex is HttpRequestException || ex is TimeoutException,
// Callback vor jedem Delay
OnRetry = (ex, attempt, delay) =>
{
Console.WriteLine($"Versuch {attempt} fehlgeschlagen. Warte {delay.TotalMilliseconds}ms. Fehler: {ex.Message}");
}
};
// Policy instanziieren
IResiliencePolicy policy = new RetryPolicy(options);
// Ausführen
try
{
string result = await policy.ExecuteAsync(async cancellationToken =>
{
// Ihre I/O oder API-Operation
return await myHttpClient.GetStringAsync("https://api.example.com/data", cancellationToken);
}, CancellationToken.None);
Console.WriteLine($"Erfolg: {result}");
}
catch (Exception ex)
{
Console.WriteLine($"Alle Versuche fehlgeschlagen: {ex.Message}");
}
2. Integration in Dependency Injection (DI)
Registrieren Sie die Policy in Ihrer Program.cs oder Ihrem Startup-Code:
using Microsoft.Extensions.DependencyInjection;
using CoreVitals.Resilience;
var services = new ServiceCollection();
// Registrierung im DI-Container
services.AddRetryPolicy(options =>
{
options.MaxRetries = 5;
options.InitialDelay = TimeSpan.FromMilliseconds(100);
options.MaxDelay = TimeSpan.FromSeconds(10);
options.ShouldRetry = ex => ex is InvalidOperationException;
});
var serviceProvider = services.BuildServiceProvider();
Konsumieren Sie die Schnittstelle IResiliencePolicy in Ihren Services:
public class MyService
{
private readonly IResiliencePolicy _resiliencePolicy;
private readonly HttpClient _httpClient;
public MyService(IResiliencePolicy resiliencePolicy, HttpClient httpClient)
{
_resiliencePolicy = resiliencePolicy;
_httpClient = httpClient;
}
public async Task<string> GetDataWithRetryAsync(CancellationToken cancellationToken)
{
return await _resiliencePolicy.ExecuteAsync(async ct =>
{
var response = await _httpClient.GetAsync("https://api.example.com/v1/resource", ct);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync(ct);
}, cancellationToken);
}
}
Konfigurationsoptionen (RetryOptions)
| Eigenschaft | Typ | Standardwert | Beschreibung |
|---|---|---|---|
MaxRetries |
int |
3 |
Maximale Anzahl an Wiederholungsversuchen. |
InitialDelay |
TimeSpan |
100ms |
Wartezeit vor dem allerersten Wiederholungsversuch. |
MaxDelay |
TimeSpan |
30s |
Obergrenze für die Verzögerung zwischen Versuchen. |
BackoffFactor |
double |
2.0 |
Der Exponent für die Berechnung der nächsten Verzögerung. |
UseJitter |
bool |
true |
Bestimmt, ob eine zufällige Abweichung (Full Jitter) auf das Delay addiert wird. |
ShouldRetry |
Func<Exception, bool> |
_ => true |
Ein Prädikat, das entscheidet, ob eine Exception für einen Retry qualifiziert ist. |
OnRetry |
Action<Exception, int, TimeSpan>? |
null |
Callback-Aktion, die aufgerufen wird, bevor die Wartezeit vor dem nächsten Retry startet. |
CI/CD & Deployment
Die Bereitstellung bei NuGet.org erfolgt vollautomatisch über GitHub Actions. Der entsprechende Workflow befindet sich unter publish.yml.
Voraussetzungen für den GitHub-Workflow (Trusted Publishing via OIDC):
- Konfiguration auf NuGet.org:
- Navigieren Sie in Ihrem NuGet.org-Konto zu Trusted Publishing.
- Fügen Sie einen neuen Trusted Publisher hinzu.
- Geben Sie den Repository-Inhaber (GitHub-Organisation oder Benutzer), den Repository-Namen sowie den exakten Namen des Workflows (
publish.yml) an.
- Keine Repository Secrets erforderlich: Die Authentifizierung erfolgt über OIDC via GitHubs Identity Provider. Es müssen keine statischen API-Schlüssel in GitHub hinterlegt oder rotiert werden.
Workflow auslösen:
- Automatisch: Der Workflow startet automatisch, sobald ein Tag mit dem Format
v*(z. B.v1.0.0) auf das Repository gepusht wird. - Manuell: Sie können den Workflow über die Registerkarte Actions in GitHub manuell triggern (
workflow_dispatch).
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
-
net10.0
-
net8.0
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 194 | 6/16/2026 |