private async Task RefreshLocationPrivateAsync(CosmosAccountSettings databaseAccount)
        {
            DefaultTrace.TraceInformation("RefreshLocationAsync() refreshing locations");

            if (databaseAccount != null)
            {
                this.locationCache.OnDatabaseAccountRead(databaseAccount);
            }

            bool canRefreshInBackground = false;

            if (this.locationCache.ShouldRefreshEndpoints(out canRefreshInBackground))
            {
                if (databaseAccount == null && !canRefreshInBackground)
                {
                    databaseAccount = await GlobalEndpointManager.GetDatabaseAccountFromAnyLocationsAsync(this.defaultEndpoint, this.connectionPolicy.PreferredLocations, this.GetDatabaseAccountAsync);

                    this.locationCache.OnDatabaseAccountRead(databaseAccount);
                }

                this.StartRefreshLocationTimerAsync();
            }
            else
            {
                this.isRefreshing = false;
            }
        }
 private Task <CosmosAccountSettings> RefreshDatabaseAccountInternalAsync()
 {
     return(this.databaseAccountCache.GetAsync(
                string.Empty,
                null,
                () => GlobalEndpointManager.GetDatabaseAccountFromAnyLocationsAsync(this.defaultEndpoint, this.connectionPolicy.PreferredLocations, this.GetDatabaseAccountAsync),
                this.cancellationTokenSource.Token,
                forceRefresh: true));
 }
示例#3
0
        public GlobalAddressResolver(
            GlobalEndpointManager endpointManager,
            Protocol protocol,
            IAuthorizationTokenProvider tokenProvider,
            CollectionCache collectionCache,
            PartitionKeyRangeCache routingMapProvider,
            UserAgentContainer userAgentContainer,
            IServiceConfigurationReader serviceConfigReader,
            HttpMessageHandler messageHandler,
            ConnectionPolicy connectionPolicy,
            ApiType apiType)
        {
            this.endpointManager     = endpointManager;
            this.protocol            = protocol;
            this.tokenProvider       = tokenProvider;
            this.userAgentContainer  = userAgentContainer;
            this.collectionCache     = collectionCache;
            this.routingMapProvider  = routingMapProvider;
            this.serviceConfigReader = serviceConfigReader;
            this.messageHandler      = messageHandler;
            this.requestTimeout      = connectionPolicy.RequestTimeout;
            this.apiType             = apiType;

            int maxBackupReadEndpoints =
                !connectionPolicy.EnableReadRequestsFallback.HasValue || connectionPolicy.EnableReadRequestsFallback.Value
                ? GlobalAddressResolver.MaxBackupReadRegions : 0;

            this.enableTcpConnectionEndpointRediscovery = connectionPolicy.EnableTcpConnectionEndpointRediscovery;

            this.maxEndpoints = maxBackupReadEndpoints + 2; // for write and alternate write endpoint (during failover)

            this.addressCacheByEndpoint = new ConcurrentDictionary <Uri, EndpointCache>();

            foreach (Uri endpoint in endpointManager.WriteEndpoints)
            {
                this.GetOrAddEndpoint(endpoint);
            }

            foreach (Uri endpoint in endpointManager.ReadEndpoints)
            {
                this.GetOrAddEndpoint(endpoint);
            }
        }
示例#4
0
        private async Task RefreshDatabaseAccountInternalAsync(bool forceRefresh)
        {
            if (this.SkipRefresh(forceRefresh))
            {
                return;
            }

            lock (this.isAccountRefreshInProgressLock)
            {
                // Check again if should refresh after obtaining the lock
                if (this.SkipRefresh(forceRefresh))
                {
                    return;
                }

                // If the refresh is already in progress just return. No reason to do another refresh.
                if (this.isAccountRefreshInProgress)
                {
                    return;
                }

                this.isAccountRefreshInProgress = true;
            }

            try
            {
#nullable disable // Needed because AsyncCache does not have nullable enabled
                AccountProperties accountProperties = await this.databaseAccountCache.GetAsync(
                    key : string.Empty,
                    obsoleteValue : null,
                    singleValueInitFunc : () => GlobalEndpointManager.GetDatabaseAccountFromAnyLocationsAsync(
                        this.defaultEndpoint,
                        this.connectionPolicy.PreferredLocations,
                        this.GetDatabaseAccountAsync),
                    cancellationToken : this.cancellationTokenSource.Token,
                    forceRefresh : true);

                this.LastBackgroundRefreshUtc = DateTime.UtcNow;
                this.locationCache.OnDatabaseAccountRead(accountProperties);
#nullable enable
            }
        public GlobalAddressResolver(
            GlobalEndpointManager endpointManager,
            GlobalPartitionEndpointManager partitionKeyRangeLocationCache,
            Protocol protocol,
            ICosmosAuthorizationTokenProvider tokenProvider,
            CollectionCache collectionCache,
            PartitionKeyRangeCache routingMapProvider,
            IServiceConfigurationReader serviceConfigReader,
            ConnectionPolicy connectionPolicy,
            CosmosHttpClient httpClient)
        {
            this.endpointManager = endpointManager;
            this.partitionKeyRangeLocationCache = partitionKeyRangeLocationCache;
            this.protocol            = protocol;
            this.tokenProvider       = tokenProvider;
            this.collectionCache     = collectionCache;
            this.routingMapProvider  = routingMapProvider;
            this.serviceConfigReader = serviceConfigReader;
            this.httpClient          = httpClient;

            int maxBackupReadEndpoints =
                !connectionPolicy.EnableReadRequestsFallback.HasValue || connectionPolicy.EnableReadRequestsFallback.Value
                ? GlobalAddressResolver.MaxBackupReadRegions : 0;

            this.enableTcpConnectionEndpointRediscovery = connectionPolicy.EnableTcpConnectionEndpointRediscovery;

            this.maxEndpoints = maxBackupReadEndpoints + 2; // for write and alternate write endpoint (during failover)

            this.addressCacheByEndpoint = new ConcurrentDictionary <Uri, EndpointCache>();

            foreach (Uri endpoint in endpointManager.WriteEndpoints)
            {
                this.GetOrAddEndpoint(endpoint);
            }

            foreach (Uri endpoint in endpointManager.ReadEndpoints)
            {
                this.GetOrAddEndpoint(endpoint);
            }
        }
        private async void StartRefreshLocationTimerAsync()
        {
            if (this.isDisposed)
            {
                return;
            }

            try
            {
                await Task.Delay(this.backgroundRefreshLocationTimeIntervalInMS);

                DefaultTrace.TraceInformation("StartRefreshLocationTimerAsync() - Invoking refresh");

                CosmosAccountSettings databaseAccount = await GlobalEndpointManager.GetDatabaseAccountFromAnyLocationsAsync(this.defaultEndpoint, this.connectionPolicy.PreferredLocations, this.GetDatabaseAccountAsync);

                await this.RefreshLocationPrivateAsync(databaseAccount);
            }
            catch (Exception ex)
            {
                DefaultTrace.TraceCritical("StartRefreshLocationTimerAsync() - Unable to refresh database account from any location. Exception: {0}", ex.ToString());
                this.StartRefreshLocationTimerAsync();
            }
        }