internal static IDriver CreateDriver(Uri uri, Config config, IPooledConnectionFactory connectionFactory) { var logger = config.Logger; var parsedUri = uri.ParseBoltUri(DefaultBoltPort); var routingContext = uri.ParseRoutingContext(DefaultBoltPort); var routingSettings = new RoutingSettings(parsedUri, routingContext, config); var metrics = config.MetricsEnabled ? new DefaultMetrics() : null; var connectionPoolSettings = new ConnectionPoolSettings(config, metrics); var retryLogic = new AsyncRetryLogic(config.MaxTransactionRetryTime, logger); EnsureNoRoutingContextOnBolt(uri, routingContext); IConnectionProvider connectionProvider = null; if (parsedUri.IsRoutingUri()) { connectionProvider = new LoadBalancer(connectionFactory, routingSettings, connectionPoolSettings, logger); } else { connectionProvider = new ConnectionPool(parsedUri, connectionFactory, connectionPoolSettings, logger, null); } return(new Internal.Driver(parsedUri, connectionProvider, retryLogic, logger, metrics, config)); }
internal static IDriver CreateDriver(Uri uri, Config config, IPooledConnectionFactory connectionFactory) { var logger = config.DriverLogger; var parsedUri = uri.ParseBoltUri(DefaultBoltPort); var routingContext = uri.ParseRoutingContext(); var routingSettings = new RoutingSettings(parsedUri, routingContext, config); var metrics = config.MetricsFactory?.CreateMetrics(config); var connectionPoolSettings = new ConnectionPoolSettings(config, metrics); var retryLogic = new AsyncRetryLogic(config.MaxTransactionRetryTime, logger); IConnectionProvider connectionProvider = null; switch (parsedUri.Scheme.ToLower()) { case "bolt": EnsureNoRoutingContext(uri, routingContext); connectionProvider = new ConnectionPool(parsedUri, connectionFactory, connectionPoolSettings, logger); break; case "bolt+routing": connectionProvider = new LoadBalancer(connectionFactory, routingSettings, connectionPoolSettings, logger); break; default: throw new NotSupportedException($"Unsupported URI scheme: {parsedUri.Scheme}"); } return(new Internal.Driver(parsedUri, connectionProvider, retryLogic, logger, metrics, config)); }
public async Task ShouldNotRetryOnSuccess() { var retryLogic = new AsyncRetryLogic(TimeSpan.FromSeconds(5), null); var work = CreateFailingWork(5); var result = await retryLogic.RetryAsync(() => work.Work(null)); result.Should().Be(5); work.Invocations.Should().Be(1); }
public async Task ShouldRetryOnTransientErrors(Exception error) { var retryLogic = new AsyncRetryLogic(TimeSpan.FromSeconds(5), null); var work = CreateFailingWork(5, error); var result = await retryLogic.RetryAsync(() => work.Work(null)); result.Should().Be(5); work.Invocations.Should().Be(2); }
public async Task ShouldNotRetryOnNonTransientErrors(Exception error) { var retryLogic = new AsyncRetryLogic(TimeSpan.FromSeconds(5), null); var work = CreateFailingWork(0, error); var exc = await Record.ExceptionAsync(() => retryLogic.RetryAsync(() => work.Work(null))); exc.Should().Be(error); work.Invocations.Should().Be(1); }
public async Task ShouldRetryAtLeastTwice() { var error = new TransientException("code", "message"); var logger = new Mock <ILogger>(); var retryLogic = new AsyncRetryLogic(TimeSpan.FromSeconds(1), logger.Object); var work = CreateFailingWork(TimeSpan.FromSeconds(2), 1, error); var result = await retryLogic.RetryAsync(() => work.Work(null)); result.Should().Be(1); logger.Verify(x => x.Warn(error, It.Is <string>(s => s.StartsWith("Transaction failed and will be retried in"))), Times.Once); }
public async Task ShouldLogRetries(int errorCount) { var error = new TransientException("code", "message"); var logger = new Mock <ILogger>(); var retryLogic = new AsyncRetryLogic(TimeSpan.FromMinutes(1), logger.Object); var work = CreateFailingWork(1, Enumerable.Range(1, errorCount).Select(x => error).Cast <Exception>().ToArray()); var result = await retryLogic.RetryAsync(() => work.Work(null)); result.Should().Be(1); logger.Verify(x => x.Warn(error, It.Is <string>(s => s.StartsWith("Transaction failed and will be retried in"))), Times.Exactly(errorCount)); }
public async Task ShouldThrowServiceUnavailableWhenRetriesTimedOut() { var errorCount = 3; var exceptions = Enumerable.Range(1, errorCount).Select(i => new TransientException($"{i}", $"{i}")) .Cast <Exception>().ToArray(); var logger = new Mock <ILogger>(); var retryLogic = new AsyncRetryLogic(TimeSpan.FromSeconds(2), logger.Object); var work = CreateFailingWork(TimeSpan.FromSeconds(1), 1, exceptions); var exc = await Record.ExceptionAsync(() => retryLogic.RetryAsync(() => work.Work(null))); exc.Should().BeOfType <ServiceUnavailableException>() .Which.InnerException.Should().BeOfType <AggregateException>() .Which.InnerExceptions.Should().BeSubsetOf(exceptions); }