in src/Microsoft.ServiceFabric.Services/Communication/Client/CommunicationClientFactoryBase.cs [207:280]
public async Task<OperationRetryControl> ReportOperationExceptionAsync(
TCommunicationClient client,
ExceptionInformation exceptionInformation,
OperationRetrySettings retrySettings,
CancellationToken cancellationToken)
{
var partitionId = client.ResolvedServicePartition.Info.Id;
var entry = this.cache.GetOrAddClientCacheEntry(
partitionId,
client.Endpoint,
client.ListenerName,
client.ResolvedServicePartition);
var faultedClient = default(TCommunicationClient);
OperationRetryControl retval;
await entry.Semaphore.WaitAsync(cancellationToken);
try
{
var handled = this.HandleReportedException(
exceptionInformation,
retrySettings,
out var exceptionHandlingResult);
if (handled && (exceptionHandlingResult is ExceptionHandlingRetryResult))
{
var retryResult = (ExceptionHandlingRetryResult)exceptionHandlingResult;
if (!retryResult.IsTransient && ReferenceEquals(client, entry.Client))
{
// The endpoint isn't valid if it is a re-triable error and not transient.
this.AbortClient(entry.Client);
faultedClient = entry.Client;
entry.Client = default(TCommunicationClient);
entry.Rsp = null;
}
retval = new OperationRetryControl()
{
ShouldRetry = true,
IsTransient = retryResult.IsTransient,
RetryDelay = retryResult.RetryDelay,
Exception = null,
ExceptionId = retryResult.ExceptionId,
MaxRetryCount = retryResult.MaxRetryCount,
GetRetryDelay = retryResult.GetRetryDelay,
};
}
else
{
retval = new OperationRetryControl()
{
ShouldRetry = false,
RetryDelay = Timeout.InfiniteTimeSpan,
Exception = exceptionInformation.Exception,
};
if ((exceptionHandlingResult is ExceptionHandlingThrowResult throwResult) && (throwResult.ExceptionToThrow != null))
{
retval.Exception = throwResult.ExceptionToThrow;
}
}
}
finally
{
entry.Semaphore.Release();
}
if (faultedClient != null && this.fireConnectEvents)
{
this.OnClientDisconnected(faultedClient);
}
return retval;
}