in src/WebJobs.Extensions.DurableTask/LocalGrpcListener.cs [56:108]
public Task StartAsync(CancellationToken cancelToken = default)
{
const int maxAttempts = 10;
int numAttempts = 1;
while (numAttempts <= maxAttempts)
{
ChannelOption[] options = new[]
{
new ChannelOption(ChannelOptions.MaxReceiveMessageLength, int.MaxValue),
new ChannelOption(ChannelOptions.MaxSendMessageLength, int.MaxValue),
};
this.grpcServer = new Server(options);
this.grpcServer.Services.Add(P.TaskHubSidecarService.BindService(new TaskHubGrpcServer(this)));
int listeningPort = numAttempts == 1 ? DefaultPort : this.GetRandomPort();
int portBindingResult = this.grpcServer.Ports.Add("localhost", listeningPort, ServerCredentials.Insecure);
if (portBindingResult != 0)
{
try
{
this.grpcServer.Start();
this.ListenAddress = $"http://localhost:{listeningPort}";
this.extension.TraceHelper.ExtensionInformationalEvent(
this.extension.Options.HubName,
instanceId: string.Empty,
functionName: string.Empty,
message: $"Opened local gRPC endpoint: {this.ListenAddress}",
writeToUserLogs: true);
return Task.CompletedTask;
}
catch (IOException)
{
portBindingResult = 0;
}
}
if (portBindingResult == 0)
{
this.extension.TraceHelper.ExtensionWarningEvent(
this.extension.Options.HubName,
functionName: string.Empty,
instanceId: string.Empty,
message: $"Failed to open local port {listeningPort}. This was attempt #{numAttempts} to open a local port.");
this.attemptedPorts.Add(listeningPort);
numAttempts++;
}
}
throw new IOException($"Unable to find a port to open an RPC endpoint on after {maxAttempts} attempts");
}