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.");
        }
示例#2
0
        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));
        }
示例#3
0
        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.");
        }
示例#4
0
        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.");
        }