bshoshany / thread-pool

BS::thread_pool: a fast, lightweight, and easy-to-use C++17 thread pool library
MIT License
2.21k stars 253 forks source link

Request URL changes if I execute it in thread_pool #35

Closed rbdm-qnt closed 2 years ago

rbdm-qnt commented 2 years ago

I'm using your lib and restclient-cpp lib to compile get and post requests and execute them in parallel to the main runtime.

This is an example version of my code:

#include "../restclient-cpp/restclient.h"
#include "../thread_pool.hpp"

enum RequestType {
  get, post, put, patch, del, head, options
};

struct Request {
  RequestType type = RequestType::get;
  std::string url;
  std::string body_type;
  std::string body;

[[nodiscard]] RestClient::Response execute() const {
switch (type) {
    case get: { std::cout << " - Inside request.h get. URL:\n" << url << "\n"; return RestClient::get(url); }
    default: { assert(false); }
    }
  }
}

Request() = default;

Request(RequestType type, std::string url): type(type), url(std::move(url)) {}
}

Request get_positions() {
  return {RequestType::get, 
  "https://api.bybit.com/private/linear/position/list"}}

void callback(const RestClient::Response& response) {
  std::cout << request.url << "\n";
}

int main(int argc, const char** argv) { 
  RestClient::init(); 
  thread_pool pool; 
  std::function<void(const RestClient::Response&)> callback = [&](const RestClient::Response& response) {
      callback(response);
    };
  Request request; 
  request = get_positions();
  std::cout << "Request url:\n" << request.url << "\n"; 
  std::cout << "Pushed to threadpool\n";
  pool.push_task([&](){ 
    callback(request.execute()); 
  }); 
}

If I call request.execute() outside of the threadpool, it gets executed normally, while if I call it in the push_task the URL of the request gets modified, it's like if the first few chars in the url string get converted to bytes or something, I can't figure it out. Those are the prints:

Request url in main thread: https://api.bybit.com/private/linear/position/list Pushed to threadpool Inside request.h get. URL: t��t.com/private/linear/position/list

I asked this question in the restclient-cpp repo issues aswell.

rjallanreal commented 2 years ago

did you try adding "pool.wait_for_tasks();" at the bottom of the main function?

Edit: You can also try changing the callback closure parameter from "(const RestClient::Response& response)" to "(const RestClient::Response response)" to allow the response being passed in to outlive the main function.

Edit2: Move semantics could also fix your issue: "(const RestClient::Response&& response)"

Edit3: I am wrong about Edit2, and there may be issues with my analysis after reading this line: "The lifetime of a temporary object may be extended by binding to a const lvalue reference or to an rvalue reference (since C++11), see reference initialization for details." from here

bshoshany commented 2 years ago

Sorry, I'm not familiar with restclient-cpp, so I'm not really sure what the problem is. However, I do not believe it is a problem with the thread pool library. This seems to have something to do with how restclient-cpp handles data internally. Hopefully someone on their repo can help.