in src/Microsoft.Azure.SignalR.Common/ServiceConnections/ServiceConnectionContainerBase.cs [523:569]
private IServiceConnection SelectConnection(ServiceMessage message)
{
IServiceConnection connection;
if (ClientConnectionScope.IsScopeEstablished)
{
// see if the execution context already has the connection stored for this container
var containers = ClientConnectionScope.OutboundServiceConnections;
if (!(containers.TryGetValue(Endpoint.UniqueIndex, out var connectionWeakReference)
&& connectionWeakReference.TryGetTarget(out connection)
&& IsActiveConnection(connection)))
{
connection = GetRandomActiveConnection();
ClientConnectionScope.OutboundServiceConnections[Endpoint.UniqueIndex] = new WeakReference<IServiceConnection>(connection);
}
}
else
{
// if it is not in scope
// if message is partitionable, use the container's partition cache, otherwise use a random connection
if (message is IPartitionableMessage partitionable)
{
var box = _partitionedCache[partitionable.PartitionKey];
if (!box.Value.TryGetTarget(out connection) || !IsActiveConnection(connection))
{
lock (box)
{
if (!box.Value.TryGetTarget(out connection) || !IsActiveConnection(connection))
{
connection = GetRandomActiveConnection();
box.Value.SetTarget(connection);
}
}
}
}
else
{
connection = GetRandomActiveConnection();
}
}
if (connection == null)
{
throw new ServiceConnectionNotActiveException();
}
return connection;
}