Skip to content

Commit 2159793

Browse files
not working version with ReadWriteLock, tbd
1 parent 6e40a4d commit 2159793

File tree

1 file changed

+45
-50
lines changed

1 file changed

+45
-50
lines changed

src/tarantool.client/LogicalConnectionManager.cs

Lines changed: 45 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ public class LogicalConnectionManager : ILogicalConnection
1717

1818
private LogicalConnection _droppableLogicalConnection;
1919

20-
private readonly ManualResetEvent _connected = new ManualResetEvent(false);
21-
22-
private readonly AutoResetEvent _reconnectAvailable = new AutoResetEvent(true);
20+
private readonly ReaderWriterLockSlim _connectionLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
2321

2422
private Timer _timer;
2523

@@ -29,13 +27,18 @@ public class LogicalConnectionManager : ILogicalConnection
2927

3028
private const int _pingTimerInterval = 100;
3129

32-
private int _pingCheckInterval = 1000;
30+
private readonly int _pingCheckInterval = 1000;
3331

3432
private DateTimeOffset _nextPingTime = DateTimeOffset.MinValue;
3533

3634
public LogicalConnectionManager(ClientOptions options)
3735
{
3836
_clientOptions = options;
37+
38+
if (_clientOptions.ConnectionOptions.PingCheckInterval >= 0)
39+
{
40+
_pingCheckInterval = _clientOptions.ConnectionOptions.PingCheckInterval;
41+
}
3942
}
4043

4144
public void Dispose()
@@ -51,26 +54,43 @@ public void Dispose()
5154

5255
public async Task Connect()
5356
{
54-
_clientOptions.LogWriter?.WriteLine($"{nameof(LogicalConnectionManager)}: Connecting...");
57+
if (!_connectionLock.TryEnterUpgradeableReadLock(_connectionTimeout))
58+
{
59+
throw ExceptionHelper.NotConnected();
60+
}
5561

56-
_connected.Reset();
62+
try
63+
{
64+
if (this.IsConnected())
65+
{
66+
return;
67+
}
5768

58-
var _newConnection = new LogicalConnection(_clientOptions, _requestIdCounter);
59-
await _newConnection.Connect();
60-
Interlocked.Exchange(ref _droppableLogicalConnection, _newConnection)?.Dispose();
69+
_clientOptions.LogWriter?.WriteLine($"{nameof(LogicalConnectionManager)}: Connecting...");
6170

62-
_connected.Set();
71+
_connectionLock.EnterWriteLock();
6372

64-
_clientOptions.LogWriter?.WriteLine($"{nameof(LogicalConnectionManager)}: Connected...");
73+
try
74+
{
75+
var _newConnection = new LogicalConnection(_clientOptions, _requestIdCounter);
76+
await _newConnection.Connect();
77+
Interlocked.Exchange(ref _droppableLogicalConnection, _newConnection)?.Dispose();
6578

66-
if (_clientOptions.ConnectionOptions.PingCheckInterval >= 0)
67-
{
68-
_pingCheckInterval = _clientOptions.ConnectionOptions.PingCheckInterval;
69-
}
79+
_clientOptions.LogWriter?.WriteLine($"{nameof(LogicalConnectionManager)}: Connected...");
7080

71-
if (_pingCheckInterval > 0)
81+
if (_pingCheckInterval > 0 && _timer == null)
82+
{
83+
//_timer = new Timer(x => CheckPing(), null, _pingTimerInterval, Timeout.Infinite);
84+
}
85+
}
86+
finally
87+
{
88+
_connectionLock.ExitWriteLock();
89+
}
90+
}
91+
finally
7292
{
73-
_timer = new Timer(x => CheckPing(), null, _pingTimerInterval, Timeout.Infinite);
93+
_connectionLock.ExitUpgradeableReadLock();
7494
}
7595
}
7696

@@ -80,19 +100,12 @@ private void CheckPing()
80100
{
81101
try
82102
{
83-
LogicalConnection savedConnection = _droppableLogicalConnection;
84-
85-
if (_nextPingTime > DateTimeOffset.UtcNow || savedConnection == null || !savedConnection.IsConnected())
103+
if (_nextPingTime > DateTimeOffset.UtcNow)
86104
{
87105
return;
88106
}
89107

90-
Task task = savedConnection.SendRequestWithEmptyResponse(_pingRequest);
91-
if (Task.WaitAny(task) != 0 || task.Status != TaskStatus.RanToCompletion)
92-
{
93-
_clientOptions.LogWriter?.WriteLine($"{nameof(LogicalConnectionManager)}: Ping failed, dropping logical conection...");
94-
savedConnection.Dispose();
95-
}
108+
Task.WaitAny(SendRequestWithEmptyResponse(_pingRequest));
96109
}
97110
finally
98111
{
@@ -105,36 +118,18 @@ private void CheckPing()
105118

106119
public bool IsConnected()
107120
{
108-
return _droppableLogicalConnection?.IsConnected() ?? false;
109-
}
110-
111-
private async Task EnsureConnection()
112-
{
113-
if (_connected.WaitOne(_connectionTimeout) && IsConnected())
114-
{
115-
return;
116-
}
117-
118-
_clientOptions.LogWriter?.WriteLine($"{nameof(LogicalConnectionManager)}: Connection lost, wait for reconnect...");
119-
120-
if (!_reconnectAvailable.WaitOne(_connectionTimeout))
121+
if (!_connectionLock.TryEnterReadLock(_connectionTimeout))
121122
{
122-
_clientOptions.LogWriter?.WriteLine($"{nameof(LogicalConnectionManager)}: Failed to get lock for reconnect");
123-
throw ExceptionHelper.NotConnected();
123+
return false;
124124
}
125125

126126
try
127127
{
128-
if (!IsConnected())
129-
{
130-
await Connect();
131-
}
132-
133-
_clientOptions.LogWriter?.WriteLine($"{nameof(LogicalConnectionManager)}: Connection reacquired");
128+
return _droppableLogicalConnection?.IsConnected() ?? false;
134129
}
135130
finally
136131
{
137-
_reconnectAvailable.Set();
132+
_connectionLock.ExitReadLock();
138133
}
139134
}
140135

@@ -148,7 +143,7 @@ private void ScheduleNextPing()
148143

149144
public async Task<DataResponse<TResponse[]>> SendRequest<TRequest, TResponse>(TRequest request) where TRequest : IRequest
150145
{
151-
await EnsureConnection();
146+
await Connect();
152147

153148
var result = await _droppableLogicalConnection.SendRequest<TRequest, TResponse>(request);
154149

@@ -159,7 +154,7 @@ public async Task<DataResponse<TResponse[]>> SendRequest<TRequest, TResponse>(TR
159154

160155
public async Task SendRequestWithEmptyResponse<TRequest>(TRequest request) where TRequest : IRequest
161156
{
162-
await EnsureConnection();
157+
await Connect();
163158

164159
await _droppableLogicalConnection.SendRequestWithEmptyResponse(request);
165160

0 commit comments

Comments
 (0)