Skip to content

Commit

Permalink
Merge branch 'microsoft:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
darrenge authored Nov 7, 2024
2 parents e64221d + 599e633 commit 550eea9
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .azure/pipelines/azure-pipelines-external-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ jobs:
inputs:
action: 'create'
gitHubConnection: ADO_to_Github_ServiceConnection
tagSource: manual
tagSource: userSpecifiedTag
tag: 'v$(Build.BuildNumber)'
title: 'Garnet v$(Build.BuildNumber)'
releaseNotesSource: input
Expand Down
85 changes: 67 additions & 18 deletions libs/client/GarnetClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ public GarnetClient(
/// </summary>
public void Connect(CancellationToken token = default)
{
socket = GetSendSocket(timeoutMilliseconds);
socket = CreateSendSocket(timeoutMilliseconds);
networkWriter = new NetworkWriter(this, socket, bufferSize, sslOptions, out networkHandler, sendPageSize, networkSendThrottleMax, logger);
networkHandler.StartAsync(sslOptions, $"{address}:{port}", token).ConfigureAwait(false).GetAwaiter().GetResult();
networkSender = networkHandler.GetNetworkSender();
Expand Down Expand Up @@ -221,7 +221,7 @@ public void Connect(CancellationToken token = default)
/// </summary>
public async Task ConnectAsync(CancellationToken token = default)
{
socket = GetSendSocket(timeoutMilliseconds);
socket = CreateSendSocket(timeoutMilliseconds);
networkWriter = new NetworkWriter(this, socket, bufferSize, sslOptions, out networkHandler, sendPageSize, networkSendThrottleMax, logger);
await networkHandler.StartAsync(sslOptions, $"{address}:{port}", token).ConfigureAwait(false);
networkSender = networkHandler.GetNetworkSender();
Expand Down Expand Up @@ -249,37 +249,86 @@ public async Task ConnectAsync(CancellationToken token = default)
}
}

Socket GetSendSocket(int millisecondsTimeout = 0)
/// <summary>
/// Create client send socket
/// </summary>
/// <param name="millisecondsTimeout"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
Socket CreateSendSocket(int millisecondsTimeout = 0)
{
var ip = IPAddress.Parse(address);
var endPoint = new IPEndPoint(ip, port);
if (!IPAddress.TryParse(address, out var ip))
{
var hostEntries = Dns.GetHostEntry(address);
// Try all available DNS entries if a hostName is provided
foreach (var addressEntry in hostEntries.AddressList)
{
var endPoint = new IPEndPoint(addressEntry, port);
if (!TryConnectSocket(endPoint, millisecondsTimeout, out var socket))
continue;
return socket;
}

// Reaching this point means we failed to establish connection from any of the provided addresses
throw new Exception($"Failed to connect at {address}:{port}");
}
else
{
var endPoint = new IPEndPoint(ip, port);
if (!TryConnectSocket(endPoint, millisecondsTimeout, out var socket))
{
// If failed here then provided endpoint does not accept connections
logger?.LogWarning("Failed to connect at {address}:{port}", ip.ToString(), port);
throw new Exception($"Failed to connect at {ip.ToString()}:{port}");
}
return socket;
}
}

var socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp)
/// <summary>
/// Try to establish connection for socket using endPoint
/// </summary>
/// <param name="endPoint"></param>
/// <param name="millisecondsTimeout"></param>
/// <param name="socket"></param>
/// <returns></returns>
bool TryConnectSocket(IPEndPoint endPoint, int millisecondsTimeout, out Socket socket)
{
socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp)
{
NoDelay = true
};

if (millisecondsTimeout > 0)
try
{
var result = socket.BeginConnect(endPoint, null, null);
result.AsyncWaitHandle.WaitOne(millisecondsTimeout, true);

if (socket.Connected)
if (millisecondsTimeout > 0)
{
socket.EndConnect(result);
var result = socket.BeginConnect(endPoint, null, null);
result.AsyncWaitHandle.WaitOne(millisecondsTimeout, true);

if (socket.Connected)
{
socket.EndConnect(result);
}
else
{
socket.Close();
throw new Exception($"Failed to connect server {address}:{port}.");
}
}
else
{
socket.Close();
throw new Exception($"Failed to connect server {address}:{port}.");
socket.Connect(endPoint);
}
}
else
catch (Exception ex)
{
socket.Connect(endPoint);
logger?.LogWarning(ex, "Failed at GarnetClient.TryConnectSocket");
socket.Dispose();
socket = null;
return false;
}

return socket;
return true;
}

async Task TimeoutChecker()
Expand Down

0 comments on commit 550eea9

Please sign in to comment.