8000 Improve ConnectWithTimeout in PooledSocket · cnblogs/EnyimMemcachedCore@44bfae8 · GitHub
[go: up one dir, main page]

Skip to content

Commit 44bfae8

Browse files
committed
Improve ConnectWithTimeout in PooledSocket
1 parent ba9b701 commit 44bfae8

File tree

1 file changed

+25
-15
lines changed

1 file changed

+25
-15
lines changed

Enyim.Caching/Memcached/PooledSocket.cs

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,20 @@ public PooledSocket(DnsEndPoint endpoint, TimeSpan connectionTimeout, TimeSpan r
4444
socket.ReceiveTimeout = rcv;
4545
socket.SendTimeout = rcv;
4646

47-
ConnectWithTimeout(socket, endpoint, timeout);
47+
if (!ConnectWithTimeout(socket, endpoint, timeout))
48+
{
49+
throw new TimeoutException($"Could not connect to {endpoint.Host}:{endpoint.Port}.");
50+
}
4851

4952
this.socket = socket;
5053
this.endpoint = endpoint;
5154

5255
this.inputStream = new NetworkStream(socket);
5356
}
5457

55-
private void ConnectWithTimeout(Socket socket, DnsEndPoint endpoint, int timeout)
58+
private bool ConnectWithTimeout(Socket socket, DnsEndPoint endpoint, int timeout)
5659
{
60+
bool connected = false;
5761
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
5862
var args = new SocketAsyncEventArgs();
5963

@@ -64,25 +68,31 @@ private void ConnectWithTimeout(Socket socket, DnsEndPoint endpoint, int timeout
6468
.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
6569
if (address == null)
6670
throw new ArgumentException(String.Format("Could not resolve host '{0}'.", endpoint.Host));
67-
args.RemoteEndPoint = new IPEndPoint(address, endpoint.Port);
68-
}
69-
else
70-
{
71-
//DnsEndPoint is not working on linux
72-
args.RemoteEndPoint = new IPEndPoint(address, endpoint.Port);
7371
}
7472

75-
using (var mres = new ManualResetEventSlim())
73+
//Learn from https://github.com/dotnet/corefx/blob/release/2.2/src/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNITcpHandle.cs#L180
74+
var cts = new CancellationTokenSource();
75+
cts.CancelAfter(timeout);
76+
void Cancel()
7677
{
77-
args.Completed += (s, e) => mres.Set();
78-
if (socket.ConnectAsync(args))
78+
if (!socket.Connected)
7979
{
80-
if (!mres.Wait(timeout))
81-
{
82-
throw new TimeoutException("Could not connect to " + endpoint);
83-
}
80+
socket.Dispose();
8481
}
8582
}
83+
cts.Token.Register(Cancel);
84+
85+
socket.Connect(address, endpoint.Port);
86+
if (socket.Connected)
87+
{
88+
connected = true;
89+
}
90+
else
91+
{
92+
socket.Dispose();
93+
}
94+
95+
return connected;
8696
}
8797

8898
public Action<PooledSocket> CleanupCallback { get; set; }

0 commit comments

Comments
 (0)
0