Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrading from 1.10.2 to 1.11.0 created large amounts of latency in API calls #1133

Open
honeysuckle1234 opened this issue Oct 28, 2024 · 2 comments

Comments

@honeysuckle1234
Copy link

honeysuckle1234 commented Oct 28, 2024

Description

When upgrading from cpr 1.10.2 to 1.11.0, our cpr::PostAsync calls started showing a large amount of latency between being sent and being received, ~1 minute in most cases, but sometimes would be indefinitely delayed.

Example/How to Reproduce

  1. Create a call: cpr::AsyncResponse response = cpr::PostAsync(cpr::Url{url}, cpr::Body{body}, headers);
  2. Wait for the request to come in: response .wait_for(0ms) == std::future_status::timeout
  3. Observe the time for the message to be 'sent' to being 'received' by another service.

Possible Fix

We downgraded back to 1.10.2, but installed Curl separately to upgrade that to 8.10.0.

Where did you get it from?

GitHub (branch e.g. master)

Additional Context/Your Environment

  • OS: Linux
  • Version: 1.10.2
  • Curl was not the issue, as using 8.10.0 worked fine in 1.10.2 and didn't produce latency.
@COM8
Copy link
Member

COM8 commented Oct 28, 2024

@honeysuckle1234 thanks for reporting!
This could be related to this PR: #1039

That's the only change I remember out of my had without looking too deep into the changes between 1.10.x and 1.11.0 related to async stuff.

Not sure if I will be able to, but I can try to look into it next weekend.

@COM8
Copy link
Member

COM8 commented Nov 24, 2024

I can not reproduce it on Fedora 41. That's what I tried:

#include <iostream>
#include <string>
#include <chrono>
#include <cpr/cpr.h>

void async() {
    size_t sum{0};
    for(size_t i = 1;; i++) {
        cpr::AsyncResponse response = cpr::PostAsync(cpr::Url{"https://google.de"});

        std::chrono::system_clock::time_point start = std::chrono::system_clock::now();

        while (true)
        {
            std::future_status status = response.wait_for(std::chrono::milliseconds(0));

            if(status == std::future_status::ready) {
                sum += std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - start).count();
                std::cout << "Ready after " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - start).count() << "ms, AVG: " << sum/i <<"\n";
                break;
            }
        }
    }
}

void direct() {
    size_t sum{0};
    for(size_t i = 1;; i++) {
        std::chrono::system_clock::time_point start = std::chrono::system_clock::now();
        cpr::Response response = cpr::Get(cpr::Url{"https://google.de"});
        sum += std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - start).count();
        std::cout << "Ready after " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - start).count() << "ms, AVG: " << sum/i <<"\n";
    }
}

int main(int argc, char** argv) {
    async(); // AVG(1.11.0) 208, AVG(1.10.2) 209
    // direct(); // AVG(1.11.0) 271, AVG(1.10.2) 272
    return 0;
}

My CMake:

cmake_minimum_required(VERSION 3.20)
project(cpr_example)

set(CMAKE_CXX_STANDARD 17)

# Set to C++ 11 if you are using cpr <= 1.9.x
# More: https://github.com/libcpr/cpr#supported-releases
# set(CMAKE_CXX_STANDARD 11)

# Set a default build type if none was specified
# Based on: https://github.com/openchemistry/tomviz/blob/master/cmake/BuildType.cmake
set(DEFAULT_BUILD_TYPE "Release")
if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
  set(DEFAULT_BUILD_TYPE "Debug")
endif()
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  message(STATUS "Setting build type to '${DEFAULT_BUILD_TYPE}' as none was specified.")
  set(CMAKE_BUILD_TYPE "${DEFAULT_BUILD_TYPE}" CACHE STRING "Choose the type of build." FORCE)
  # Set the possible values of build type for cmake-gui
  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()

add_executable(cpr_example main.cpp)

if(WIN32) # Install dlls in the same directory as the executable on Windows
    set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
endif()

include(FetchContent)
FetchContent_Declare(cpr GIT_REPOSITORY https://github.com/libcpr/cpr.git
                         GIT_TAG 1.11.0) # 1.10.2
FetchContent_MakeAvailable(cpr)

target_link_libraries(cpr_example PRIVATE cpr::cpr)

Could you please provide an example for me to reproduce?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants