function requiredDiscoverEndpoint(request, done) {
	  var service = request.service;
	  var api = service.api;
	  var operationModel = api.operations ? api.operations[request.operation] : undefined;
	  var inputShape = operationModel ? operationModel.input : undefined;

	  var identifiers = marshallCustomIdentifiers(request, inputShape);
	  var cacheKey = getCacheKey(request);
	  if (Object.keys(identifiers).length > 0) {
	    cacheKey = util.update(cacheKey, identifiers);
	    if (operationModel) cacheKey.operation = operationModel.name;
	  }
	  var cacheKeyStr = AWS.EndpointCache.getKeyString(cacheKey);
	  var endpoints = AWS.endpointCache.get(cacheKeyStr); //endpoint cache also accepts string keys
	  if (endpoints && endpoints.length === 1 && endpoints[0].Address === '') {
	    //endpoint operation is being made but response not yet received
	    //push request object to a pending queue
	    if (!requestQueue[cacheKeyStr]) requestQueue[cacheKeyStr] = [];
	    requestQueue[cacheKeyStr].push({request: request, callback: done});
	    return;
	  } else if (endpoints && endpoints.length > 0) {
	    request.httpRequest.updateEndpoint(endpoints[0].Address);
	    done();
	  } else {
	    var endpointRequest = service.makeRequest(api.endpointOperation, {
	      Operation: operationModel.name,
	      Identifiers: identifiers,
	    });
	    endpointRequest.removeListener('validate', AWS.EventListeners.Core.VALIDATE_PARAMETERS);
	    addApiVersionHeader(endpointRequest);

	    //put in a placeholder for endpoints already requested, prevent
	    //too much in-flight calls
	    AWS.endpointCache.put(cacheKeyStr, [{
	      Address: '',
	      CachePeriodInMinutes: 60 //long-live cache
	    }]);
	    endpointRequest.send(function(err, data) {
	      if (err) {
	        request.response.error = util.error(err, { retryable: false });
	        AWS.endpointCache.remove(cacheKey);

	        //fail all the pending requests in batch
	        if (requestQueue[cacheKeyStr]) {
	          var pendingRequests = requestQueue[cacheKeyStr];
	          util.arrayEach(pendingRequests, function(requestContext) {
	            requestContext.request.response.error = util.error(err, { retryable: false });
	            requestContext.callback();
	          });
	          delete requestQueue[cacheKeyStr];
	        }
	      } else if (data) {
	        AWS.endpointCache.put(cacheKeyStr, data.Endpoints);
	        request.httpRequest.updateEndpoint(data.Endpoints[0].Address);

	        //update the endpoint for all the pending requests in batch
	        if (requestQueue[cacheKeyStr]) {
	          var pendingRequests = requestQueue[cacheKeyStr];
	          util.arrayEach(pendingRequests, function(requestContext) {
	            requestContext.request.httpRequest.updateEndpoint(data.Endpoints[0].Address);
	            requestContext.callback();
	          });
	          delete requestQueue[cacheKeyStr];
	        }
	      }
	      done();
	    });
	  }
	}
Call endpoint discovery operation when it's required.
When endpoint is available in cache then use cached ones. If endpoints are
unavailable then SDK should call endpoint operation then use returned new
endpoint for the api call. SDK will automatically attempt to do endpoint
discovery. This is turned off by default
@param [object] request object
@api private