0

For certain reasons I'm trying to use libcpr::PostCallback to send requests, and a customized callback function to parse responses for later use.

Since libcpr::PostCallback use std::future as its return value, so I implemented a thread-safe list to store them, and a class to handle the whole list:

class FutureList {
 public:
  FutureList();
  ~FutureList();
  std::list<std::future<std::string>>::iterator Begin();
  std::list<std::future<std::string>>::iterator End();

  void Erase(std::list<std::future<std::string>>::iterator& it);
  bool Empty();
  void PushBack(std::future<std::string>&& rvalue);

 private:
  std::mutex list_mtx_;
  std::list<std::future<std::string>> list_;
};


class FutureHandler {
 public:
  FutureHandler();
  ~FutureHandler();

  /*
    some other functions
  */

  void Handle();

 private:
  FutureList future_list_;
};

Here's the main logic that how I process the whole list.

void FutureHandler::Handle() {
  std::future_status status;
  auto it = future_list_.Begin();

  while (it != future_list_.End()) {
    status = it->wait_for(std::chrono::milliseconds(1));
    if (status != std::future_status::ready) {
      ++it;
      continue;
    }

    // Since the response would be parsed by callback function, 
    // we only print the plaintext to check if the response is correct.
    // std::cout << "http responses: " << it->get() << std::endl;

    future_list_.Erase(it);
  }
  return;
}

Currently I've got correct http responses if the http server is alive, but I'm wondering that what would happened if http server goes down for some reason (which cause libcpr::Timeout/ConnectionTimeout), and what's the behavior of std::future in such situation?

starskyTW
  • 21
  • 2
  • 1
    This would be fairly easy to test (just point your requests into the void), but just glancing at the docs I'll assume that your callback will just get a response with a status of 0 and an error. They'll still complete, and the return will still be whatever your callback returns (which could be an `optional`/`variant`/`expected` etc.). Also, slightly OT, but you should probably have `Erase` return an iterator, like `list::erase` does, since the iterator is likely invalidated. – Hasturkun Dec 22 '22 at 09:40

0 Answers0