internal async Task <IRoutingTable> UpdateRoutingTableAsync(AccessMode mode, string database, Bookmark bookmark) { if (database == null) { throw new ArgumentNullException(nameof(database)); } _logger?.Debug("Updating routing table for database '{0}'.", database); var existingTable = RoutingTableFor(database); if (existingTable == null) { existingTable = new RoutingTable(database, Enumerable.Empty <Uri>()); } var hasPrependedInitialRouters = false; if (existingTable.IsReadingInAbsenceOfWriter(mode)) { var uris = _initialServerAddressProvider.Get(); await PrependRoutersAsync(existingTable, uris).ConfigureAwait(false); hasPrependedInitialRouters = true; } var triedUris = new HashSet <Uri>(); var newRoutingTable = await UpdateRoutingTableAsync(existingTable, mode, database, bookmark, triedUris) .ConfigureAwait(false); if (newRoutingTable != null) { return(newRoutingTable); } if (!hasPrependedInitialRouters) { var uris = _initialServerAddressProvider.Get(); uris.ExceptWith(triedUris); if (uris.Count != 0) { await PrependRoutersAsync(existingTable, uris).ConfigureAwait(false); newRoutingTable = await UpdateRoutingTableAsync(existingTable, mode, database, bookmark) .ConfigureAwait(false); if (newRoutingTable != null) { return(newRoutingTable); } } } // We tried our best however there is just no cluster. // This is the ultimate place we will inform the user that a new driver to be created. throw new ServiceUnavailableException( "Failed to connect to any routing server. " + "Please make sure that the cluster is up and can be accessed by the driver and retry."); }
public async Task <bool> SupportsMultiDbAsync() { var uris = _initialServerAddressProvider.Get(); await AddConnectionPoolAsync(uris).ConfigureAwait(false); var exceptions = new List <Exception>(); foreach (var uri in uris) { try { var connection = await CreateClusterConnectionAsync(uri, Simple.Mode, Simple.Database, Simple.Bookmark).ConfigureAwait(false); var multiDb = connection.SupportsMultidatabase(); await connection.CloseAsync().ConfigureAwait(false); return(multiDb); } catch (SecurityException) { throw; // immediately stop } catch (Exception e) { exceptions.Add(e); // save and continue with the next server } } throw new ServiceUnavailableException( $"Failed to perform multi-databases feature detection with the following servers: {uris.ToContentString()} ", new AggregateException(exceptions)); }
internal async Task <IRoutingTable> UpdateRoutingTableWithInitialUriFallbackAsync( Func <ISet <Uri>, Task <IRoutingTable> > updateRoutingTableFunc = null) { _logger?.Debug("Updating routing table."); var hasPrependedInitialRouters = false; if (IsReadingInAbsenceOfWriter) { var uris = _initialServerAddressProvider.Get(); await PrependRoutersAsync(uris).ConfigureAwait(false); hasPrependedInitialRouters = true; } var triedUris = new HashSet <Uri>(); var routingTable = await UpdateRoutingTableAsync(triedUris).ConfigureAwait(false); if (routingTable != null) { return(routingTable); } if (!hasPrependedInitialRouters) { var uris = _initialServerAddressProvider.Get(); uris.ExceptWith(triedUris); if (uris.Count != 0) { await PrependRoutersAsync(uris).ConfigureAwait(false); routingTable = await UpdateRoutingTableAsync(null).ConfigureAwait(false); if (routingTable != null) { return(routingTable); } } } // We retied and tried our best however there is just no cluster. // This is the ultimate place we will inform the user that you need to re-create a driver throw new ServiceUnavailableException( "Failed to connect to any routing server. " + "Please make sure that the cluster is up and can be accessed by the driver and retry."); }
internal IRoutingTable UpdateRoutingTableWithInitialUriFallback( Func <ISet <Uri>, IRoutingTable> updateRoutingTableFunc = null) { updateRoutingTableFunc = updateRoutingTableFunc ?? (u => UpdateRoutingTable(u)); var hasPrependedInitialRouters = false; if (IsReadingInAbsenceOfWriter) { // to prevent from only talking to minority part of a partitioned cluster. PrependRouters(_initialServerAddressProvider.Get()); hasPrependedInitialRouters = true; } var triedUris = new HashSet <Uri>(); var routingTable = updateRoutingTableFunc(triedUris); if (routingTable != null) { return(routingTable); } if (!hasPrependedInitialRouters) { var uris = _initialServerAddressProvider.Get(); uris.ExceptWith(triedUris); if (uris.Count != 0) { PrependRouters(uris); routingTable = updateRoutingTableFunc(null); if (routingTable != null) { return(routingTable); } } } // We retied and tried our best however there is just no cluster. // This is the ultimate place we will inform the user that you need to re-create a driver throw new ServiceUnavailableException( "Failed to connect to any routing server. " + "Please make sure that the cluster is up and can be accessed by the driver and retry."); }