MXS-1754 Add possibility to cancel delayed calls

The interface for canceling calls is now geared towards the needs
of sessions. Basically the idea is as follows:

class MyFilterSession : public maxscale::FilterSession
{
    ...
    int MyFilterSession::routeQuery(GWBUF* pPacket)
    {
       ...
       if (needs_to_be_delayed())
       {
           Worker* pWorker = Worker::current();
           void* pTag = this;
           pWorker->delayed_call(5000, pTag, this,
                                 &MyFilterSession::delayed_routeQuery,
                                 pPacket);
           return 1;
       }
       ...
    }

    bool MyFilterSession::delayed_routeQuery(Worker::Call:action_t action,
                                             GWBUF* pPacket)
    {
        if (action == Worker::Call::EXECUTE)
        {
            routeQuery(pPacket);
        }
        else
        {
            ss_dassert(action == Worker::Call::CANCEL);
            gwbuf_free(pPacket);
        }
        return false;
    }

    ~MyFilterSession()
    {
        void* pTag = this;
        Worker::current()->cancel_delayed_calls(pTag);
    }
}

The alternative, returning some key that the caller must keep
around seems more cumbersome for the general case.
This commit is contained in:
Johan Wikman
2018-04-20 09:16:10 +03:00
parent 84b2156508
commit be9504ac94
3 changed files with 178 additions and 47 deletions

View File

@ -78,8 +78,10 @@ public:
return m_delay;
}
bool tick()
bool tick(mxs::Worker::Call::action_t action)
{
ss_dassert(action == mxs::Worker::Call::EXECUTE);
int64_t now = get_monotonic_time_ms();
int64_t diff = abs(now - m_at);
@ -127,11 +129,11 @@ int run()
TimerTest t4(&rv, 500);
TimerTest t5(&rv, 600);
w.delayed_call(t1.delay(), &t1, &TimerTest::tick);
w.delayed_call(t2.delay(), &t2, &TimerTest::tick);
w.delayed_call(t3.delay(), &t3, &TimerTest::tick);
w.delayed_call(t4.delay(), &t4, &TimerTest::tick);
w.delayed_call(t5.delay(), &t5, &TimerTest::tick);
w.delayed_call(t1.delay(), NULL, &t1, &TimerTest::tick);
w.delayed_call(t2.delay(), NULL, &t2, &TimerTest::tick);
w.delayed_call(t3.delay(), NULL, &t3, &TimerTest::tick);
w.delayed_call(t4.delay(), NULL, &t4, &TimerTest::tick);
w.delayed_call(t5.delay(), NULL, &t5, &TimerTest::tick);
w.run();