Skip to content

Commit 5eb98fa

Browse files
cnblogs-dudusanikachavan5
authored andcommitted
refactor: deal with socket disposed exception
1 parent 6f150b2 commit 5eb98fa

File tree

2 files changed

+82
-46
lines changed

2 files changed

+82
-46
lines changed

src/Enyim.Caching/Memcached/MemcachedNode.cs

Lines changed: 50 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
using AEPLCore.Monitoring;
22
using Enyim.Caching.Configuration;
3-
using Enyim.Caching.Memcached.Protocol.Binary;
43
using Enyim.Caching.Memcached.Results;
54
using Enyim.Caching.Memcached.Results.Extensions;
6-
using Enyim.Collections;
75
using Microsoft.Extensions.Logging;
86
using System;
97
using System.Collections.Concurrent;
@@ -13,8 +11,6 @@
1311
using System.Net;
1412
using System.Net.Security;
1513
using System.Net.Sockets;
16-
using System.Runtime.Serialization;
17-
using System.Security;
1814
using System.Threading;
1915
using System.Threading.Tasks;
2016

@@ -1014,49 +1010,71 @@ protected internal virtual PooledSocket CreateSocket()
10141010
{
10151011
try
10161012
{
1017-
var ps = new PooledSocket(_endPoint, _config.ConnectionTimeout, _config.ReceiveTimeout, _logger,
1018-
#if NET5_0_OR_GREATER
1019-
_useSslStream, _useIPv6, _sslClientAuthOptions);
1020-
#else
1021-
_useSslStream, _useIPv6);
1022-
#endif
1023-
ps.Connect();
1024-
return ps;
1013+
return CreateSocketInternal();
10251014
}
1026-
catch (Exception ex)
1015+
catch
10271016
{
1028-
_logger.LogError(ex, $"Create {nameof(PooledSocket)}");
1029-
throw;
1017+
try
1018+
{
1019+
return CreateSocketInternal();
1020+
}
1021+
catch (Exception ex)
1022+
{
1023+
LogCreateSocketError(ex, nameof(CreateSocket));
1024+
throw;
1025+
}
10301026
}
10311027
}
10321028

1033-
protected internal virtual async Task<PooledSocket> CreateSocketAsync()
1029+
private PooledSocket CreateSocketInternal()
10341030
{
1035-
try
1036-
{
1037-
var ps = new PooledSocket(_endPoint, _config.ConnectionTimeout, _config.ReceiveTimeout, _logger,
1031+
var ps = new PooledSocket(_endPoint, _config.ConnectionTimeout, _config.ReceiveTimeout, _logger,
10381032
#if NET5_0_OR_GREATER
1039-
_useSslStream, _useIPv6, _sslClientAuthOptions);
1033+
_useSslStream, _useIPv6, _sslClientAuthOptions);
10401034
#else
1041-
_useSslStream, _useIPv6);
1035+
_useSslStream, _useIPv6);
10421036
#endif
1043-
await ps.ConnectAsync();
1044-
return ps;
1037+
ps.Connect();
1038+
return ps;
1039+
}
1040+
1041+
protected internal virtual async Task<PooledSocket> CreateSocketAsync()
1042+
{
1043+
try
1044+
{
1045+
return await CreateSocketInternalAsync();
10451046
}
1046-
catch (Exception ex)
1047+
catch
10471048
{
1048-
var endPointStr = _endPoint.ToString().Replace("Unspecified/", string.Empty);
1049-
_logger.LogError(ex, $"Failed to {nameof(CreateSocketAsync)} to {endPointStr}");
1050-
throw;
1049+
try
1050+
{
1051+
return await CreateSocketInternalAsync();
1052+
}
1053+
catch (Exception ex)
1054+
{
1055+
LogCreateSocketError(ex, nameof(CreateSocketAsync));
1056+
throw;
1057+
}
10511058
}
10521059
}
10531060

1054-
//protected internal virtual PooledSocket CreateSocket(IPEndPoint endpoint, TimeSpan connectionTimeout, TimeSpan receiveTimeout)
1055-
//{
1056-
// PooledSocket retval = new PooledSocket(endPoint, connectionTimeout, receiveTimeout);
1061+
private async Task<PooledSocket> CreateSocketInternalAsync()
1062+
{
1063+
var ps = new PooledSocket(_endPoint, _config.ConnectionTimeout, _config.ReceiveTimeout, _logger,
1064+
#if NET5_0_OR_GREATER
1065+
_useSslStream, _useIPv6, _sslClientAuthOptions);
1066+
#else
1067+
_useSslStream, _useIPv6);
1068+
#endif
1069+
await ps.ConnectAsync();
1070+
return ps;
1071+
}
10571072

1058-
// return retval;
1059-
//}
1073+
private void LogCreateSocketError(Exception ex, string operation)
1074+
{
1075+
var endPointStr = _endPoint.ToString().Replace("Unspecified/", string.Empty);
1076+
_logger.LogError(ex, "Failed to {operation} to {EndPoint}", operation, endPointStr);
1077+
}
10601078

10611079
protected virtual IPooledSocketResult ExecuteOperation(IOperation op)
10621080
{

src/Enyim.Caching/Memcached/PooledSocket.cs

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ public partial class PooledSocket : IDisposable
1818
private readonly ILogger _logger;
1919

2020
private bool _isAlive;
21-
private bool _useSslStream;
22-
private bool _useIPv6;
21+
private readonly bool _useSslStream;
22+
private readonly bool _useIPv6;
2323
private Socket _socket;
24+
private bool _isSocketDisposed;
2425
private readonly EndPoint _endpoint;
2526
private readonly int _connectionTimeout;
2627

@@ -75,7 +76,7 @@ public PooledSocket(EndPoint endpoint, TimeSpan connectionTimeout, TimeSpan rece
7576
_socket = socket;
7677
}
7778

78-
public void Connect()
79+
public bool Connect()
7980
{
8081
bool success = false;
8182

@@ -87,20 +88,21 @@ void Cancel()
8788
{
8889
if (_socket != null && !_socket.Connected)
8990
{
90-
_socket.Dispose();
91-
_socket = null;
91+
DisposeSocket();
9292
}
9393
}
9494

9595
cts.Token.Register(Cancel);
9696

9797
try
9898
{
99+
if (_isSocketDisposed) return false;
99100
_socket.Connect(_endpoint);
100101
}
101102
catch (PlatformNotSupportedException)
102103
{
103104
var ep = GetIPEndPoint(_endpoint);
105+
if (_isSocketDisposed) return false;
104106
_socket.Connect(ep.Address, ep.Port);
105107
}
106108

@@ -113,8 +115,7 @@ void Cancel()
113115
}
114116
else
115117
{
116-
_socket.Dispose();
117-
_socket = null;
118+
DisposeSocket();
118119
}
119120
}
120121

@@ -135,17 +136,24 @@ void Cancel()
135136
{
136137
_inputStream = new NetworkStream(_socket);
137138
}
139+
140+
return true;
138141
}
139142
else
140143
{
141144
throw new TimeoutException($"Could not connect to {_endpoint}.");
142145
}
143146
}
144147

145-
public async Task ConnectAsync()
148+
public async Task<bool> ConnectAsync()
146149
{
147150
bool success = false;
148151

152+
if (_isSocketDisposed)
153+
{
154+
return false;
155+
}
156+
149157
try
150158
{
151159
var connTask = _socket.ConnectAsync(_endpoint);
@@ -158,8 +166,7 @@ public async Task ConnectAsync()
158166
{
159167
if (_socket != null)
160168
{
161-
_socket.Dispose();
162-
_socket = null;
169+
DisposeSocket();
163170
}
164171

165172
throw new TimeoutException($"Timeout to connect to {_endpoint}.");
@@ -168,6 +175,7 @@ public async Task ConnectAsync()
168175
catch (PlatformNotSupportedException)
169176
{
170177
var ep = GetIPEndPoint(_endpoint);
178+
if (_isSocketDisposed) return false;
171179
await _socket.ConnectAsync(ep.Address, ep.Port);
172180
}
173181

@@ -180,8 +188,7 @@ public async Task ConnectAsync()
180188
}
181189
else
182190
{
183-
_socket.Dispose();
184-
_socket = null;
191+
DisposeSocket();
185192
}
186193
}
187194

@@ -202,6 +209,8 @@ await _sslStream.AuthenticateAsClientAsync(
202209
{
203210
_inputStream = new NetworkStream(_socket);
204211
}
212+
213+
return true;
205214
}
206215
else
207216
{
@@ -336,7 +345,7 @@ protected void Dispose(bool disposing)
336345
}
337346
catch (Exception e)
338347
{
339-
_logger.LogError(nameof(PooledSocket), e);
348+
_logger.LogError(e, nameof(PooledSocket));
340349
}
341350
}
342351
else
@@ -355,8 +364,17 @@ void IDisposable.Dispose()
355364

356365
private void CheckDisposed()
357366
{
358-
if (_socket == null)
367+
if (_isSocketDisposed || _socket == null)
368+
{
359369
throw new ObjectDisposedException("PooledSocket");
370+
}
371+
}
372+
373+
private void DisposeSocket()
374+
{
375+
_isSocketDisposed = true;
376+
_socket.Dispose();
377+
_socket = null;
360378
}
361379

362380
/// <summary>

0 commit comments

Comments
 (0)