Table of Contents
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.