Caution
The following article is based an old version of the client library. Please make changes accordingly.
Failover
In this use case the client implements transient fault handling policy using the .NET library Polly.
The following code is only an implementation sketch, and the client is free to elaborate on it.
Note
We assume the client is familiar with the MdClientSession class for connection to the server (see MdClientSession Configuration and Establishing a Connection).
1. Availability model
The Tooq Tech Feed Handler works with an active-active availability model: in case of connection loss, the client may either retry connection or switch over to a secondary server.
For both primary and secondary servers we associate an IP address and a port number.
public readonly Dictionary<string, Tuple<string, int>> servers = new()
{
{ "primary", Tuple.Create("192.168.0.1", 10_003) },
{ "secondary", Tuple.Create("192.168.0.10", 10_005) }
};
We also define a static MdClientSession
instance to connect to a server and a static string to indicate the current server.
public static MdClientSession session;
public static string currentServer;
2. Declaring a failover policy
You can use Polly to define transient failure handling policies. In this case we implement a failover approach where for every ConnectionException
we execute the SwitchOver
method to change server, including a delay of 30 milliseconds.
var failoverPolicy = Policy
.Handle<ConnectionException>()
.WaitAndRetryForeverAsync
(
sleepDurationProvider: (attempt, context) => TimeSpan.FromMilliseconds(30),
onRetry: SwitchServer
);
The SwitchServer
simply sets currentServer
.
void SwitchServer(Exception ex, TimeSpan timeSpan, Context context)
{
currentServer = currentServer switch
{
"primary" => "secondary",
"secondary" => "primary",
_ => "primary"
};
}
Remark: the paramenter context
is a Polly.Context
instance (see Using Execution Context in Polly).
3. Executing policy
Once the policy is declared, you need to indicate how to execute it.
PolicyResult result = await faioverPolicy.ExecuteAndCaptureAsync(() => Task.Run(() => SetClientSession()));
Where the SetClientSessison
method is where the connection is actually made.
void SetClientSession()
{
currentServer = currentServer ?? "primary";
var IP = servers[currentServer].Item1;
var port = servers[currentServer].Item2;
var config = new SessionConfiguration(IP, port, true);
if (session != null) UnsubscribeFromEvents();
session = new(config);
SubscribeToEvents();
session.Connect();
}
The methods SubscribeToEvents
and UnsubscribeFromEvents
should involve all events of interest to your application;
void SubscribeToEvents()
{
session.Connected += OnConnected;
session.Disconnected += OnDisconnected;
// ...
}
void UnsubscribeFromEvents()
{
session.Connected -= OnConnected;
session.Disconnected -= OnDisconnected;
// ...
}
Remark: The unsubscription from all events is necessary to avoid remaining references to the old content of session
, hence avoiding memory leak.
4. More elaborate policies
The Polly library allows for many fault handling policies like Retry, Timeout, Circut Breaker etc. (see Readme).
We also note that you may define more specific exceptions to be handled in a policy and that different policies may be declared for different servers.