@@ -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