All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.microsoft.azure.documentdb.internal.EndpointDiscoveryRetryPolicy Maven / Gradle / Ivy

package com.microsoft.azure.documentdb.internal;

import java.net.URI;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.microsoft.azure.documentdb.ConnectionPolicy;
import com.microsoft.azure.documentdb.DocumentClientException;

final class EndpointDiscoveryRetryPolicy implements RetryPolicy {
    private final static int MAX_RETRY_COUNT = 120;
    private final static int RETRY_INTERVAL_IN_MS = 1000;
    private final static Logger LOGGER = LoggerFactory.getLogger(EndpointDiscoveryRetryPolicy.class);
    private final EndpointManager globalEndpointManager;
    private final ConnectionPolicy connectionPolicy;
    private final DocumentServiceRequest request;
    private URI locationEndpoint;
    private int failoverRetryCount = 0;
    
    /**
     * A RetryPolicy implementation that handles endpoint change exceptions.
     * @param connectionPolicy connection policy
     * @param globalEndpointManager endpoint manager
     */
    public EndpointDiscoveryRetryPolicy(ConnectionPolicy connectionPolicy,
                                        EndpointManager globalEndpointManager,
                                        DocumentServiceRequest request) {
        this.connectionPolicy = connectionPolicy;
        this.globalEndpointManager = globalEndpointManager;
        
        // clear previous location-based routing directive
        request.clearRouteToLocation();

        // Resolve the endpoint for the request and pin the resolution to the resolved endpoint
        // This enables marking the endpoint unavailability on endpoint failover/unreachability
        this.locationEndpoint = this.globalEndpointManager.resolveServiceEndpoint(request);
        request.routeToLocation(this.locationEndpoint);
        
        this.request = request;
    }

    /**
     * Gets the number of milliseconds to wait before retry the operation.
     *
     * @return the number of milliseconds to wait before retry the operation.
     */
    public long getRetryAfterInMilliseconds() {
        if (!this.request.isReadOnlyRequest()) {
            return this.failoverRetryCount <= 1 ?
                    0 :
                    RETRY_INTERVAL_IN_MS; // if retried both endpoints, follow regular retry intervals
        } else {
            return RETRY_INTERVAL_IN_MS;
        }
    }

    /**
     * Should the caller retry the operation.
     * 

* This retry policy should only be invoked if HttpStatusCode is 403 (Forbidden) * and SubStatusCode is 3 (WriteForbidden). * * @param exception the exception to check. * @return true if should retry. */ public boolean shouldRetry(DocumentClientException exception) { if (!this.connectionPolicy.getEnableEndpointDiscovery()) { return false; } if (this.failoverRetryCount >= MAX_RETRY_COUNT) { return false; } this.failoverRetryCount++; if (this.locationEndpoint != null) { if (request.isReadOnlyRequest()) { // Mark current read endpoint as unavailable globalEndpointManager.markEndpointUnavailableForRead(this.locationEndpoint); } else { globalEndpointManager.markEndpointUnavailableForWrite(this.locationEndpoint); } } if (!this.request.isReadOnlyRequest()) { LOGGER.debug(String.format("Failover happening. retryCount %d", this.failoverRetryCount)); } boolean forceRefresh = exception.getSubStatusCode() != null && exception.getSubStatusCode() == HttpConstants.SubStatusCodes.FORBIDDEN_WRITEFORBIDDEN; this.globalEndpointManager.refreshEndpointList(null, forceRefresh); // clear previous location-based routing directive request.clearRouteToLocation(); // set location-based routing directive based on retry count // simulating single master writes by ensuring usePreferredLocations // is set to false request.routeToLocation(this.failoverRetryCount, false); // Resolve the endpoint for the request and pin the resolution to the resolved endpoint // This enables marking the endpoint unavailability on endpoint failover/unreachability this.locationEndpoint = this.globalEndpointManager.resolveServiceEndpoint(request); request.routeToLocation(this.locationEndpoint); return true; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy