File tree Expand file tree Collapse file tree 3 files changed +20
-9
lines changed
src/MongoDB.Driver.Core/Core/Servers
tests/MongoDB.Driver.Core.Tests/Core/Servers Expand file tree Collapse file tree 3 files changed +20
-9
lines changed Original file line number Diff line number Diff line change @@ -84,8 +84,6 @@ public void Dispose()
84
84
85
85
public async Task RunAsync ( )
86
86
{
87
- await Task . Yield ( ) ; // return control immediately
88
-
89
87
while ( ! _cancellationToken . IsCancellationRequested )
90
88
{
91
89
try
Original file line number Diff line number Diff line change @@ -128,7 +128,14 @@ public void Initialize()
128
128
{
129
129
if ( _state . TryChange ( State . Initial , State . Open ) )
130
130
{
131
- _ = MonitorServerAsync ( ) . ConfigureAwait ( false ) ;
131
+ // the call to Task.Factory.StartNew is not normally recommended or necessary
132
+ // we are using it temporarily to work around a race condition in some of our tests
133
+ // the issue is that we set up some mocked async methods to return results immediately synchronously
134
+ // which results in the MonitorServerAsync method making more progress synchronously than the test expected
135
+ // by using Task.Factory.StartNew we introduce a short delay before the MonitorServerAsync Task starts executing
136
+ // the delay is whatever time it takes for the new Task to be activated and scheduled
137
+ // and the delay is usually long enough for the test to get past the race condition (though not guaranteed)
138
+ _ = Task . Factory . StartNew ( ( ) => _ = MonitorServerAsync ( ) . ConfigureAwait ( false ) ) . ConfigureAwait ( false ) ;
132
139
_ = _roundTripTimeMonitor . RunAsync ( ) . ConfigureAwait ( false ) ;
133
140
}
134
141
}
@@ -189,8 +196,6 @@ private async Task<IConnection> InitializeConnectionAsync(CancellationToken canc
189
196
190
197
private async Task MonitorServerAsync ( )
191
198
{
192
- await Task . Yield ( ) ; // return control immediately
193
-
194
199
var metronome = new Metronome ( _serverMonitorSettings . HeartbeatInterval ) ;
195
200
var monitorCancellationToken = _monitorCancellationTokenSource . Token ;
196
201
Original file line number Diff line number Diff line change 14
14
*/
15
15
16
16
using System ;
17
+ using System . Diagnostics ;
17
18
using System . Threading ;
18
19
using System . Threading . Tasks ;
19
20
using FluentAssertions ;
@@ -38,13 +39,20 @@ public void Dispose_can_be_called_multiple_times()
38
39
public void RequestHeartbeat_should_respect_to_minHeartbeatInterval ( [ Values ( 10 , - 1 ) ] int heartbeatIntervalInMinutes )
39
40
{
40
41
var heartbeatInterval = heartbeatIntervalInMinutes == - 1 ? Timeout . InfiniteTimeSpan : TimeSpan . FromMinutes ( heartbeatIntervalInMinutes ) ;
41
- var subject = new HeartbeatDelay ( heartbeatInterval , TimeSpan . FromSeconds ( 2 ) ) ;
42
+ var minHeartbeatInterval = TimeSpan . FromSeconds ( 2 ) ;
42
43
44
+ var stopwatch = Stopwatch . StartNew ( ) ;
45
+ var subject = new HeartbeatDelay ( heartbeatInterval , minHeartbeatInterval ) ;
43
46
subject . RequestHeartbeat ( ) ;
47
+ var timeout = TimeSpan . FromMinutes ( 1 ) ;
48
+ var result = Task . WaitAny ( subject . Task , Task . Delay ( timeout ) ) ;
49
+ if ( result != 0 )
50
+ {
51
+ throw new Exception ( $ "The test timeout { timeout } is exceeded.") ;
52
+ }
53
+ stopwatch . Stop ( ) ;
44
54
45
- SpinWait . SpinUntil ( ( ) => subject . Task . Status != TaskStatus . WaitingForActivation , TimeSpan . FromMilliseconds ( 1500 ) ) . Should ( ) . BeFalse ( ) ;
46
- Thread . Sleep ( TimeSpan . FromMilliseconds ( 700 ) ) ;
47
- subject . Task . Status . Should ( ) . Be ( TaskStatus . RanToCompletion ) ;
55
+ stopwatch . Elapsed . Should ( ) . BeGreaterOrEqualTo ( minHeartbeatInterval - TimeSpan . FromMilliseconds ( 15 ) ) ;
48
56
}
49
57
50
58
[ Fact ]
You can’t perform that action at this time.
0 commit comments