Flow Control
Features⌗
Condition: fluent condition aggregator; collects failure messages and can throwConditionFailedExceptionor convert to a process output.ConditionFailedException: exception carrying all collected error messages asstring[].Retry: simple retry with configurable max attempts and fixed delay; supportsActionandFunc<T>.JitteredWaiter: exponential backoff with jitter; exposesCanRetryand throwsMaxRetriesReachedExceptionwhen retries are exhausted.MaxRetriesReachedException: exception thrown whenJitteredWaiterexceeds its retry limit.
Class Diagram⌗
classDiagram
namespace FlowControl {
class Condition {
-HashSet~string~ _failedConditions
-bool _expression
+static Condition Create
+string[] FailedConditions
+bool IsSatisfied
+Condition True(bool expression)
+Condition False(bool expression)
+Condition FailsWith(string error)
+void ThrowIfNotSatisfied()
+ProcessOutput ToProcessOutput()
}
class ConditionFailedException {
+string[] Errors
}
class Retry {
-int _delayMilliseconds
-int _maxAttempts
+static Retry New
+Retry MaxAttempts(int maxAttempts)
+Retry DelayMilliseconds(int delayMilliseconds)
+void Execute(Action action)
+T Execute~T~(Func~T~ func)
}
}
namespace FlowControl_Waiter {
class JitteredWaiter {
-const int FixedWaitDelay
+int MaxRetryCount
-int Count
+bool CanRetry
+Task Wait()
}
class MaxRetriesReachedException
}
Condition ..> ConditionFailedException : throws
JitteredWaiter ..> MaxRetriesReachedException : throws
Usage⌗
Condition⌗
Chain boolean assertions — all failures are collected before throwing:
using ArturRios.Util.FlowControl;
Condition.Create
.True(user is not null).FailsWith("User is required")
.True(emailValid).FailsWith("Invalid email format")
.False(string.IsNullOrEmpty(username)).FailsWith("Username cannot be empty")
.ThrowIfNotSatisfied();
Convert to a process output instead of throwing:
var result = Condition.Create
.True(age >= 18).FailsWith("Must be 18 or older")
.ToProcessOutput();
if (!result.Success)
Console.WriteLine(string.Join(", ", result.Errors));
Retry⌗
Retry a void action:
using ArturRios.Util.FlowControl;
Retry.New
.MaxAttempts(3)
.DelayMilliseconds(200)
.Execute(() => SendEmail(recipient));
Retry a function that returns a value:
var data = Retry.New
.MaxAttempts(5)
.DelayMilliseconds(500)
.Execute(() => FetchDataFromApi());
JitteredWaiter⌗
Use in a polling or retry loop with exponential backoff:
using ArturRios.Util.FlowControl.Waiter;
var waiter = new JitteredWaiter(maxRetryCount: 5);
while (waiter.CanRetry)
{
try
{
await TryOperationAsync();
break;
}
catch (TransientException)
{
await waiter.Wait();
}
}