runtime::next_outcome runtime::get_next()

in src/runtime.cpp [225:311]


runtime::next_outcome runtime::get_next()
{
    http::response resp;
    set_curl_next_options();
    curl_easy_setopt(m_curl_handle, CURLOPT_WRITEDATA, &resp);
    curl_easy_setopt(m_curl_handle, CURLOPT_HEADERDATA, &resp);

    curl_slist* headers = nullptr;
    headers = curl_slist_append(headers, m_user_agent_header.c_str());
    curl_easy_setopt(m_curl_handle, CURLOPT_HTTPHEADER, headers);

    logging::log_debug(LOG_TAG, "Making request to %s", m_endpoints[Endpoints::NEXT].c_str());
    CURLcode curl_code = curl_easy_perform(m_curl_handle);
    logging::log_debug(LOG_TAG, "Completed request to %s", m_endpoints[Endpoints::NEXT].c_str());
    curl_slist_free_all(headers);

    if (curl_code != CURLE_OK) {
        logging::log_debug(LOG_TAG, "CURL returned error code %d - %s", curl_code, curl_easy_strerror(curl_code));
        logging::log_error(LOG_TAG, "Failed to get next invocation. No Response from endpoint");
        return aws::http::response_code::REQUEST_NOT_MADE;
    }

    {
        long resp_code;
        curl_easy_getinfo(m_curl_handle, CURLINFO_RESPONSE_CODE, &resp_code);
        resp.set_response_code(static_cast<aws::http::response_code>(resp_code));
    }

    {
        char* content_type = nullptr;
        curl_easy_getinfo(m_curl_handle, CURLINFO_CONTENT_TYPE, &content_type);
        resp.set_content_type(content_type);
    }

    if (!is_success(resp.get_response_code())) {
        logging::log_error(
            LOG_TAG,
            "Failed to get next invocation. Http Response code: %d",
            static_cast<int>(resp.get_response_code()));
        return resp.get_response_code();
    }

    auto out = resp.get_header(REQUEST_ID_HEADER);
    if (!out.is_success()) {
        logging::log_error(LOG_TAG, "Failed to find header %s in response", REQUEST_ID_HEADER);
        return aws::http::response_code::REQUEST_NOT_MADE;
    }
    invocation_request req;
    req.payload = resp.get_body();
    req.request_id = std::move(out).get_result();

    out = resp.get_header(TRACE_ID_HEADER);
    if (out.is_success()) {
        req.xray_trace_id = std::move(out).get_result();
    }

    out = resp.get_header(CLIENT_CONTEXT_HEADER);
    if (out.is_success()) {
        req.client_context = std::move(out).get_result();
    }

    out = resp.get_header(COGNITO_IDENTITY_HEADER);
    if (out.is_success()) {
        req.cognito_identity = std::move(out).get_result();
    }

    out = resp.get_header(FUNCTION_ARN_HEADER);
    if (out.is_success()) {
        req.function_arn = std::move(out).get_result();
    }

    out = resp.get_header(DEADLINE_MS_HEADER);
    if (out.is_success()) {
        auto const& deadline_string = std::move(out).get_result();
        constexpr int base = 10;
        unsigned long ms = strtoul(deadline_string.c_str(), nullptr, base);
        assert(ms > 0);
        assert(ms < ULONG_MAX);
        req.deadline += std::chrono::milliseconds(ms);
        logging::log_info(
            LOG_TAG,
            "Received payload: %s\nTime remaining: %" PRId64,
            req.payload.c_str(),
            static_cast<int64_t>(req.get_time_remaining().count()));
    }
    return {req};
}