mercredi 19 avril 2017

Combining a thread_pool with a deadline_timer - issues with template (time)

I have integrated Boost's asio service and used it in conjunction with a thread pool.

Having created a thread pool which handles both futures and async tasks, I am wanting to expand it a bit further to handle deadline timers too (anti-pattern?). Unfortunately, I am hitting my limit in comprehension of handling templated code. To be more precise, I would like to pass a boost::posix_time (ex: boost::posix_time::milliseconds(100) or boost::posix_time::seconds(5) ), but I am struggling to understand how I could make this possible.

The partial listing of code below is the current implementation of my thread pool.

//////////////////////////////////////////////////////////////////////////
class thread_pool
{
public:

    // ...
    // Other boring stuff here...


    //////////////////////////////////////////////////////////////////////////
    template<class Task>
    void enqueue_async(Task task)
    {
        m_pIO->post( std::bind(&thread_pool::wrap_task, this,
                                                  std::function< void() >( task )));
    }

    //////////////////////////////////////////////////////////////////////////
    // NOTE: Needing help here - 'expiry_time' should be relative.
    template <class Task, class ???>
    void enqueue_deadline_async(Task task, const ??? & expiry_time)
    {
        const std::shared_ptr<boost::asio::basic_deadline_timer<???> > apTimer = std::make_shared<boost::asio::deadline_timer>(*get_service_pointer(), expiry_time);
        apTimer->async_wait(std::bind(&thread_pool::enqueue_async, this, task));
    }

private:

    //////////////////////////////////////////////////////////////////////////
    void wrap_task( std::function< void() > task )
    {
        try
        {
            task();
        }
        catch (const std::exception &e)
        {
            // Todo: Log that there is a problem!!
            BOOST_ASSERT_MSG(0,e.what());
        }
    }

};

Up until this point, I have been using the enqueue_task(...) to queue an asynchronous task for processing by the thread pool. I would now like to expand the thread pool to be able to asynchronously call a callback parameter to a deadline timer (see enqueue_deadline_async()) BUT let the thread pool handle the task.

The reason to integrate the thread_pool with a deadline_time is to:

  • Minimize the number of io_services running concurrently in code.
  • Prevent a deadline_time from blocking the io_service too long - decrease the impact on other pending timers.

Finally, are my nested calls in the io_service dangerous?

Environment Configuration:

  • Ubuntu v17.04 (Zesty) x86_x64
  • Boost v1.63
  • GCC 6.3

Aucun commentaire:

Enregistrer un commentaire