public void ToTimeout_should_return_the_amount_of_time_left() { var subject = new SlidingTimeout(TimeSpan.FromMilliseconds(20), _clock); subject.ToTimeout().Should().Be(TimeSpan.FromMilliseconds(20)); _clock.UtcNow = _clock.UtcNow.AddMilliseconds(10); subject.ToTimeout().Should().Be(TimeSpan.FromMilliseconds(10)); _clock.UtcNow = _clock.UtcNow.AddMilliseconds(10); subject.ToTimeout().Should().Be(TimeSpan.Zero); }
public void ToTimeout_should_throw_a_TimeoutException_when_the_timeout_has_expired() { var subject = new SlidingTimeout(TimeSpan.FromMilliseconds(20), _clock); _clock.UtcNow = _clock.UtcNow.AddMilliseconds(30); Action act = () => subject.ToTimeout(); act.ShouldThrow <TimeoutException>(); }
// public methods public async Task<IConnectionHandle> AcquireConnectionAsync(TimeSpan timeout, CancellationToken cancellationToken) { ThrowIfNotOpen(); var slidingTimeout = new SlidingTimeout(timeout); bool enteredWaitQueue = false; bool enteredPool = false; Stopwatch stopwatch = new Stopwatch(); try { if (_listener != null) { _listener.ConnectionPoolBeforeEnteringWaitQueue(_serverId); } stopwatch.Start(); enteredWaitQueue = _waitQueue.Wait(0); // don't wait... if (!enteredWaitQueue) { throw new MongoException("Too many waiters in the connection pool."); } stopwatch.Stop(); if(_listener != null) { _listener.ConnectionPoolAfterEnteringWaitQueue(_serverId, stopwatch.Elapsed); _listener.ConnectionPoolBeforeCheckingOutAConnection(_serverId); } stopwatch.Restart(); var waitQueueTimeout = (int)Math.Min(slidingTimeout.ToTimeout().TotalMilliseconds, timeout.TotalMilliseconds); if (waitQueueTimeout == Timeout.Infinite) { // if one of these is infinite (-1), then we don't timeout properly waitQueueTimeout = (int)Math.Max(slidingTimeout.ToTimeout().TotalMilliseconds, timeout.TotalMilliseconds); } enteredPool = await _poolQueue.WaitAsync(TimeSpan.FromMilliseconds(waitQueueTimeout), cancellationToken); if (enteredPool) { var acquired = AcquireConnection(); stopwatch.Stop(); if (_listener != null) { _listener.ConnectionPoolAfterCheckingOutAConnection(acquired.ConnectionId, stopwatch.Elapsed); } return acquired; } stopwatch.Stop(); var message = string.Format("Timed out waiting for a connection after {0}ms.", stopwatch.ElapsedMilliseconds); throw new TimeoutException(message); } catch (Exception ex) { if (enteredPool) { try { _poolQueue.Release(); } catch { // TODO: log this, but don't throw... it's a bug if we get here } } if (_listener != null) { if (!enteredWaitQueue) { _listener.ConnectionPoolErrorEnteringWaitQueue(_serverId, stopwatch.Elapsed, ex); } else { _listener.ConnectionPoolErrorCheckingOutAConnection(_serverId, stopwatch.Elapsed, ex); } } throw; } finally { if (enteredWaitQueue) { try { _waitQueue.Release(); } catch { // TODO: log this, but don't throw... it's a bug if we get here } } } }
public void ToTimeout_should_return_infinite_TimeSpan_when_expiration_is_MaxValue() { var subject = new SlidingTimeout(Timeout.InfiniteTimeSpan); subject.ToTimeout().Should().Be(Timeout.InfiniteTimeSpan); }
public void ToTimeout_should_throw_a_TimeoutException_when_the_timeout_has_expired() { var subject = new SlidingTimeout(TimeSpan.FromMilliseconds(20), _clock); _clock.UtcNow = _clock.UtcNow.AddMilliseconds(30); Action act = () => subject.ToTimeout(); act.ShouldThrow<TimeoutException>(); }
public void ToTimeout_should_return_the_amount_of_time_left() { var subject = new SlidingTimeout(TimeSpan.FromMilliseconds(20), _clock); subject.ToTimeout().Should().Be(TimeSpan.FromMilliseconds(20)); _clock.UtcNow = _clock.UtcNow.AddMilliseconds(10); subject.ToTimeout().Should().Be(TimeSpan.FromMilliseconds(10)); _clock.UtcNow = _clock.UtcNow.AddMilliseconds(10); subject.ToTimeout().Should().Be(TimeSpan.Zero); }
public void ToTimeout_should_return_infinite_TimeSpan_when_expiration_is_MaxValue() { var subject = new SlidingTimeout(Timeout.InfiniteTimeSpan); subject.ToTimeout().Should().Be(Timeout.InfiniteTimeSpan); }