yhirose/cpp-httplib

How to access the Response object from within the TaskQueue.

marcovc opened this issue · 4 comments

Hi,

I'm trying to come up with a task queue that will reject requests with a given message whenever there is no worker available to process the request (unlike the default ThreadPool that queues the request).

I thought I could just inherit from ThreadPool, and override this method:

void enqueue(std::function<void()> fn) override

Then if there are no workers available, I would like to reject the request. But the question is, how can I access the request inside this method?

Or maybe there is a simpler way to achieve this?

Thanks!

@marcovc thanks for the question. The workers don't expose the state (active or inactive). So we cannot know how many workers are available. Only thing I came up with is to write your own thread pool. You can first copy the default ThreadPool implementation, and add a member variable like available_worker_count, and control the value in each worker class. When enqueue is called, you can reject a request if available_worker_count is full. Sorry that I cannot show a simple solution, but hope it helps!

I guess my main question is still how to reject a request from inside the thread pool (since there is no reference to request there).

@marcovc I am still not sure what your question really means. So I'll just explain what the worker class does. Please see the added comments in the worker class. In your situation, it seems to be better to make your own TaskQueue instead of inheriting the default ThreadPool, because the default one only considers simple general situations. Sorry that I am not able to give you clear answer...

  struct worker {
    explicit worker(ThreadPool &pool) : pool_(pool) {}

    void operator()() {
      for (;;) {
        // Waiting a request
        std::function<void()> fn;
        {
          std::unique_lock<std::mutex> lock(pool_.mutex_);

          // Waiting a signal from `enqueue()` or `shutdown()`
          pool_.cond_.wait(
              lock, [&] { return !pool_.jobs_.empty() || pool_.shutdown_; });

          // Finish this thread and return when shutdown and there is no job
          if (pool_.shutdown_ && pool_.jobs_.empty()) { break; }

          // Pick a job from the queue
          fn = std::move(pool_.jobs_.front());
          pool_.jobs_.pop_front();
        }

        // Run a job in this thread
        assert(true == static_cast<bool>(fn));
        fn();
      }
    }