namespace Cepis; /// /// How a behaves. Every setting has a default; the /// one that usually changes between environments is . /// /// /// /// using var client = new CepisClient(new CepisClientOptions /// { /// BaseUrl = "http://localhost:8080", /// TotalTimeout = TimeSpan.FromSeconds(15), /// }); /// /// public sealed record CepisClientOptions { /// /// Where the API lives. Defaults to . /// /// /// Point it at a local instance or at a test server. A trailing slash is /// stripped when the client is built, so it cannot produce doubled /// separators that some proxies normalise and others answer 404 to. /// public string BaseUrl { get; init; } = CepisClient.DefaultUrl; /// /// How long a single attempt may take, connection included. Defaults to ten /// seconds. /// /// /// It is not a cap on the whole call: with three attempts and the waits /// between them, the worst case is roughly three times this plus the /// backoffs. is the cap on the whole call. /// public TimeSpan Timeout { get; init; } = TimeSpan.FromSeconds(10); /// /// How many attempts in total, counting the first. Defaults to three. /// /// /// 1 disables retrying. The default of 3 covers the common /// case, one transient failure, without turning a real outage into a long /// wait. /// public int MaxAttempts { get; init; } = 3; /// /// The base of the exponential wait between attempts. Defaults to 500 /// milliseconds. /// /// /// The actual wait is drawn from [0, base * 2^(n-1)] — full jitter. /// The randomness is not decoration: without it, N clients that fail /// together come back together and reproduce the spike that took the /// service down. /// public TimeSpan BackoffBase { get; init; } = TimeSpan.FromMilliseconds(500); /// /// The cap on each individual wait. Defaults to eight seconds. /// /// /// It applies to a server-sent Retry-After too, or a /// Retry-After: 3600 from a misconfigured proxy would park the /// caller for an hour. /// public TimeSpan BackoffMax { get; init; } = TimeSpan.FromSeconds(8); /// /// The cap on the whole call, attempts and waits included. Unset by /// default. /// /// /// leaves as the only /// bound. Set it in code serving a web request: without it the worst case /// is times plus the sum of /// the backoffs. /// public TimeSpan? TotalTimeout { get; init; } /// /// Overrides the User-Agent. uses the /// default. /// /// /// The default identifies the library and its version, which is what lets /// the server diagnose an old client misbehaving. /// public string? UserAgent { get; init; } }