In our system, we have one C++ component acting as a Thrift Server, and one .netCore/C# component as a client. So far, I was managing a single connection, so using a singleton to create my ThriftPushClientWrapper which implements TBaseClient. (via the generated object from the thrift interface)
.AddSingleton<IThriftPushClientWrapper>(sp =>
{
var localIpAddress = IPAddress.Parse(serverIp);
var transport = new TSocketTransport(localIpAddress, dataPort);
var protocol = new TBinaryProtocol(transport);
return new ThriftPushClientWrapper(protocol);
});
(so far using 0.13 version of the Thrift library, need to update to 0.14.1 soon, but wonder if the server part must be updated too/first). This is working great.
Now, I want multiple clients that can connect to the server simultaneously, all on the same ip:port So I am starting a ClientFactory, but wonder how to deal with the creation of the client. To be more precise, the server part is configured for 5 threads, so I need 5 clients.
One simple approach would be to create a new client each time, but probably inefficient.
A better approach is to have a collection of 5 clients, and using the next available free one. So I started with the following factory, where I should get the index from outside.
private readonly ConcurrentDictionary<int, IThriftPushClientWrapper> _clientDict;
public IThriftPushClientWrapper GetNextAvailablePushClient(int index)
{
IThriftPushClientWrapper client;
if (_clientDict.ContainsKey(index))
{
if (_clientDict.TryGetValue(index, out client) && client != null)
return client;
else // error handling
}
// add new client for the expecting index
client = CreateNewPushClient();
_clientDict.TryAdd(index, client);
return client;
}
private IThriftPushClientWrapper CreateNewPushClient()
{
var localIpAddress = IPAddress.Parse(serverIp);
var transport = new TSocketTransport(localIpAddress, dataPort);
var protocol = new TBinaryProtocol(transport);
return new ThriftPushClientWrapper(protocol);
}
My next issue it to determine how to set the index from outside. I started with a SemaphoreSlim(5,5) using the semaphore.CurrentCount as index, but probably not the best idea. Also tried with a rolling index from 0 to 5. But apparently, a CancellationToken is used to cancel further procceesing. Not sure the root cause yet.
Is it possible to determine whether a TBaseClient is currently busy or available?
What is the recommended strategy to deal with a pool of clients?