🧱 Creating a Resilient Service
Here’s a complete, minimal but meaningful example of how to write a custom ResilientService
that implements IConnectable
, simulating connection behavior and integrating with Altruist’s resilient service lifecycle.
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Altruist;
public class DummyResilientService : IConnectable
{
private bool _connected;
private int _connectionAttempts;
public string ServiceName => "DummyResilientService";
public bool IsConnected => _connected;
public event Action? OnConnected;
public event Action<Exception>? OnFailed;
public event Action<Exception>? OnRetryExhausted;
// accept connection info, configuration etc here, in the constructor
public DummyResilientService()
{
}
// retrying for 1 minute max
public async Task ConnectAsync(int maxRetries = 30, int delayMilliseconds = 2000)
{
_connected = false;
_connectionAttempts = 0;
while (!_connected && _connectionAttempts < maxRetries)
{
_connectionAttempts++;
try
{
// Simulate work — this is where real connection logic would be
await Task.Delay(500);
// Simulate random success/failure (for demo)
if (_connectionAttempts >= 3)
{
_connected = true;
RaiseConnectedEvent();
return;
}
throw new Exception("Simulated connection failure");
}
catch (Exception ex)
{
RaiseFailedEvent(ex);
}
}
if (!_connected)
{
// Irreversible error, Altruist will shutdown the server.
RaiseOnRetryExhaustedEvent(new Exception("Max retries reached."));
}
}
// we implement these for now, in the future Altruist will provide a default implementation
public void RaiseConnectedEvent()
{
OnConnected?.Invoke();
}
public void RaiseFailedEvent(Exception ex)
{
OnFailed?.Invoke(ex);
}
public void RaiseOnRetryExhaustedEvent(Exception ex)
{
OnRetryExhausted?.Invoke(ex);
}
}
🧩 Registering in DI
In your app's Program.cs
or Startup.cs
, you can wire this up like so:
builder.Services.AddSingleton<IConnectable, DummyResilientService>();
Note:
This is what makes it truly resilient by letting Altruist auto-discover and monitor the service during startup, handling connection lifecycle for you.
🧪 What Happens
- During app startup, Altruist calls
ConnectAsync()
. - The service simulates connection attempts.
- After 3 failed attempts, it connects successfully and raises
OnConnected
. - If it never connects, it raises
OnRetryExhausted
and the app shuts down gracefully (per Altruist's defaultServerStatus
logic).
💡 Use Cases
This structure makes it easy to create services for:
- External databases or caches
- Game-specific third-party APIs
- Gateways or message brokers (e.g., Kafka, NATS)
- Monitoring or analytics services
- Or just dummy services used for local dev/testing