void AwsSmithyClientBase::AttemptOneRequestAsync()

in src/aws-cpp-sdk-core/source/smithy/client/AwsSmithyClientBase.cpp [316:444]


void AwsSmithyClientBase::AttemptOneRequestAsync(std::shared_ptr<AwsSmithyClientAsyncRequestContext> pRequestCtx) const
{
    if(!pRequestCtx)
    {
        assert(!"Missing pRequestCtx");
        AWS_LOGSTREAM_FATAL(AWS_SMITHY_CLIENT_LOG, "Missing request context!");
    }
    auto& responseHandler = pRequestCtx->m_responseHandler;
    auto pExecutor = pRequestCtx->m_pExecutor;

    //This is extracted here so that on retry with correct region, signer region override is honored
    UpdateAuthSchemeFromEndpoint(pRequestCtx->m_endpoint, pRequestCtx->m_authSchemeOption);

    TracingUtils::MakeCallWithTiming(
      [&]() -> void {
          pRequestCtx->m_httpRequest = BuildHttpRequest(pRequestCtx, pRequestCtx->m_endpoint.GetURI(), pRequestCtx->m_method);
      },
      TracingUtils::SMITHY_CLIENT_SERIALIZATION_METRIC,
      *m_clientConfig->telemetryProvider->getMeter(this->GetServiceClientName(), {}),
      {{TracingUtils::SMITHY_METHOD_DIMENSION, pRequestCtx->m_requestName},
       {TracingUtils::SMITHY_SERVICE_DIMENSION, this->GetServiceClientName()}});

    if (!pRequestCtx->m_httpRequest)
    {
        AWS_LOGSTREAM_ERROR(AWS_SMITHY_CLIENT_LOG, "Failed to BuildHttpRequest");
        auto outcome = HttpResponseOutcome(ClientError(CoreErrors::VALIDATION, "", "Unable to create HttpRequest object", false/*retryable*/));
        pExecutor->Submit([outcome, responseHandler]() mutable
          {
              responseHandler(std::move(outcome));
          } );
        return;
    }

    pRequestCtx->m_interceptorContext->SetTransmitRequest(pRequestCtx->m_httpRequest);
    for (const auto& interceptor : m_interceptors)
    {
        auto modifiedRequest = interceptor->ModifyBeforeSigning(*pRequestCtx->m_interceptorContext);
        if (!modifiedRequest.IsSuccess())
        {
            pExecutor->Submit([modifiedRequest, responseHandler]() mutable
              {
                  responseHandler(modifiedRequest.GetError());
              });
            return;
        }
    }

    Aws::Monitoring::CoreMetricsCollection coreMetrics;
    pRequestCtx->m_monitoringContexts = Aws::Monitoring::OnRequestStarted(this->GetServiceClientName(),
                                                                          pRequestCtx->m_requestName,
                                                                          pRequestCtx->m_httpRequest);

    if(m_clientConfig->retryStrategy && !m_clientConfig->retryStrategy->HasSendToken())
    {
        auto errOutcome = HttpResponseOutcome(ClientError(CoreErrors::SLOW_DOWN,
                                                                "",
                                                                "Unable to acquire enough send tokens to execute request.",
                                                                false/*retryable*/));
        pExecutor->Submit([errOutcome, responseHandler]() mutable
          {
              responseHandler(std::move(errOutcome));
          } );
        return;
    };

    SigningOutcome signingOutcome = TracingUtils::MakeCallWithTiming<SigningOutcome>([&]() -> SigningOutcome {
            return this->SignHttpRequest(pRequestCtx->m_httpRequest, *pRequestCtx);
        },
        TracingUtils::SMITHY_CLIENT_SIGNING_METRIC,
        *m_clientConfig->telemetryProvider->getMeter(this->GetServiceClientName(), {}),
        {{TracingUtils::SMITHY_METHOD_DIMENSION, pRequestCtx->m_requestName},
         {TracingUtils::SMITHY_SERVICE_DIMENSION, this->GetServiceClientName()}});

    if (!signingOutcome.IsSuccess())
    {
        AWS_LOGSTREAM_ERROR(AWS_SMITHY_CLIENT_LOG, "Request signing failed. Returning error.");
        auto errOutcome = HttpResponseOutcome(ClientError(CoreErrors::CLIENT_SIGNING_FAILURE, "", "SDK failed to sign the request", false/*retryable*/));
        pRequestCtx->m_pExecutor->Submit([errOutcome, pRequestCtx]() mutable
          {
              pRequestCtx->m_responseHandler(std::move(errOutcome));
          } );
        return;
    }

    std::shared_ptr<Aws::Http::HttpRequest> signedHttpRequest = signingOutcome.GetResultWithOwnership();
    assert(signedHttpRequest);

    if (pRequestCtx->m_pRequest && pRequestCtx->m_pRequest->GetRequestSignedHandler())
    {
        pRequestCtx->m_pRequest->GetRequestSignedHandler()(*signedHttpRequest);
    }

    // handler for a single http reply (vs final AWS response handler)
    auto httpResponseHandler = [this, pRequestCtx](std::shared_ptr<Aws::Http::HttpResponse> pResponse) mutable
    {
        HandleAsyncReply(std::move(pRequestCtx), std::move(pResponse));
    };

    // TODO: async http client
#if 0
    AWS_LOGSTREAM_DEBUG(AWS_SMITHY_CLIENT_LOG, "Request Successfully signed");
    TracingUtils::MakeCallWithTiming(
        [&]() -> void {
            m_httpClient->MakeAsyncRequest(pRequestCtx->m_httpRequest,
                                           pRequestCtx->m_pExecutor,
                                           responseHandler,
                                           m_clientConfig->readRateLimiter.get(),
                                           m_clientConfig->writeRateLimiter.get());
    },
    TracingUtils::SMITHY_CLIENT_SERVICE_CALL_METRIC,
    *m_clientConfig->telemetryProvider->getMeter(this->GetServiceClientName(), {}),
    {{TracingUtils::SMITHY_METHOD_DIMENSION, pRequestCtx->m_requestName},
     {TracingUtils::SMITHY_SERVICE_DIMENSION, this->GetServiceClientName()}});
#else
    auto httpResponse = TracingUtils::MakeCallWithTiming<std::shared_ptr<HttpResponse>>(
        [&]() -> std::shared_ptr<HttpResponse> {
            return m_httpClient->MakeRequest(signedHttpRequest, m_clientConfig->readRateLimiter.get(), m_clientConfig->writeRateLimiter.get());
        },
        TracingUtils::SMITHY_CLIENT_SERVICE_CALL_METRIC,
        *m_clientConfig->telemetryProvider->getMeter(this->GetServiceClientName(), {}),
        {{TracingUtils::SMITHY_METHOD_DIMENSION, pRequestCtx->m_requestName},{TracingUtils::SMITHY_SERVICE_DIMENSION, this->GetServiceClientName()}});

    pRequestCtx->m_pExecutor->Submit([httpResponse, httpResponseHandler]() mutable
      {
          httpResponseHandler(std::move(httpResponse));
      } );
#endif
    return;
}