summaryrefslogtreecommitdiffstats
path: root/src/Cepis/CepisClientOptions.cs
diff options
context:
space:
mode:
authorMurilo Ijanc <[email protected]>2026-07-26 12:42:38 -0300
committerMurilo Ijanc <[email protected]>2026-07-26 13:10:34 -0300
commita2b10fd494fb389e556e40134031eb86e56e11e7 (patch)
tree08b6df8a06f2c7c15488b90d57a6d8286cd57a22 /src/Cepis/CepisClientOptions.cs
downloadcsharp-a2b10fd494fb389e556e40134031eb86e56e11e7.tar.gz
Initial importv0.1.0
Diffstat (limited to 'src/Cepis/CepisClientOptions.cs')
-rw-r--r--src/Cepis/CepisClientOptions.cs92
1 files changed, 92 insertions, 0 deletions
diff --git a/src/Cepis/CepisClientOptions.cs b/src/Cepis/CepisClientOptions.cs
new file mode 100644
index 0000000..ea9234d
--- /dev/null
+++ b/src/Cepis/CepisClientOptions.cs
@@ -0,0 +1,92 @@
+namespace Cepis;
+
+/// <summary>
+/// How a <see cref="CepisClient"/> behaves. Every setting has a default; the
+/// one that usually changes between environments is <see cref="BaseUrl"/>.
+/// </summary>
+/// <example>
+/// <code>
+/// using var client = new CepisClient(new CepisClientOptions
+/// {
+/// BaseUrl = "http://localhost:8080",
+/// TotalTimeout = TimeSpan.FromSeconds(15),
+/// });
+/// </code>
+/// </example>
+public sealed record CepisClientOptions
+{
+ /// <summary>
+ /// Where the API lives. Defaults to <see cref="CepisClient.DefaultUrl"/>.
+ /// </summary>
+ /// <remarks>
+ /// 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.
+ /// </remarks>
+ public string BaseUrl { get; init; } = CepisClient.DefaultUrl;
+
+ /// <summary>
+ /// How long a single attempt may take, connection included. Defaults to ten
+ /// seconds.
+ /// </summary>
+ /// <remarks>
+ /// 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. <see cref="TotalTimeout"/> is the cap on the whole call.
+ /// </remarks>
+ public TimeSpan Timeout { get; init; } = TimeSpan.FromSeconds(10);
+
+ /// <summary>
+ /// How many attempts in total, counting the first. Defaults to three.
+ /// </summary>
+ /// <remarks>
+ /// <c>1</c> disables retrying. The default of <c>3</c> covers the common
+ /// case, one transient failure, without turning a real outage into a long
+ /// wait.
+ /// </remarks>
+ public int MaxAttempts { get; init; } = 3;
+
+ /// <summary>
+ /// The base of the exponential wait between attempts. Defaults to 500
+ /// milliseconds.
+ /// </summary>
+ /// <remarks>
+ /// The actual wait is drawn from <c>[0, base * 2^(n-1)]</c> — 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.
+ /// </remarks>
+ public TimeSpan BackoffBase { get; init; } = TimeSpan.FromMilliseconds(500);
+
+ /// <summary>
+ /// The cap on each individual wait. Defaults to eight seconds.
+ /// </summary>
+ /// <remarks>
+ /// It applies to a server-sent <c>Retry-After</c> too, or a
+ /// <c>Retry-After: 3600</c> from a misconfigured proxy would park the
+ /// caller for an hour.
+ /// </remarks>
+ public TimeSpan BackoffMax { get; init; } = TimeSpan.FromSeconds(8);
+
+ /// <summary>
+ /// The cap on the whole call, attempts and waits included. Unset by
+ /// default.
+ /// </summary>
+ /// <remarks>
+ /// <see langword="null"/> leaves <see cref="MaxAttempts"/> as the only
+ /// bound. Set it in code serving a web request: without it the worst case
+ /// is <see cref="MaxAttempts"/> times <see cref="Timeout"/> plus the sum of
+ /// the backoffs.
+ /// </remarks>
+ public TimeSpan? TotalTimeout { get; init; }
+
+ /// <summary>
+ /// Overrides the <c>User-Agent</c>. <see langword="null"/> uses the
+ /// default.
+ /// </summary>
+ /// <remarks>
+ /// The default identifies the library and its version, which is what lets
+ /// the server diagnose an old client misbehaving.
+ /// </remarks>
+ public string? UserAgent { get; init; }
+}