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.
162 lines
3.0 KiB
C++
162 lines
3.0 KiB
C++
/*
|
|
* Copyright (c) 2016 MariaDB Corporation Ab
|
|
*
|
|
* Use of this software is governed by the Business Source License included
|
|
* in the LICENSE.TXT file and at www.mariadb.com/bsl11.
|
|
*
|
|
* Change Date: 2020-01-01
|
|
*
|
|
* On the date above, in accordance with the Business Source License, use
|
|
* of this software will be governed by version 2 or later of the General
|
|
* Public License.
|
|
*/
|
|
|
|
#include <iostream>
|
|
#include "../internal/worker.hh"
|
|
|
|
using namespace std;
|
|
|
|
namespace
|
|
{
|
|
|
|
// TODO: Put this in some common place.
|
|
int64_t get_monotonic_time_ms()
|
|
{
|
|
struct timespec ts;
|
|
ss_debug(int rv =) clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
ss_dassert(rv == 0);
|
|
|
|
return ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
|
|
}
|
|
|
|
class TestWorker : public maxscale::Worker
|
|
{
|
|
TestWorker(const TestWorker&);
|
|
TestWorker& operator = (const TestWorker&);
|
|
|
|
public:
|
|
TestWorker()
|
|
{
|
|
}
|
|
|
|
~TestWorker()
|
|
{
|
|
}
|
|
|
|
private:
|
|
// TODO: Perhaps these could have default implementations, so that
|
|
// TODO: Worker could be used as such.
|
|
bool pre_run() // override
|
|
{
|
|
return true;
|
|
}
|
|
|
|
void post_run() // override
|
|
{
|
|
}
|
|
|
|
void epoll_tick() // override
|
|
{
|
|
}
|
|
};
|
|
|
|
class TimerTest
|
|
{
|
|
public:
|
|
static int s_ticks;
|
|
|
|
TimerTest(int* pRv, int32_t delay)
|
|
: m_id(s_id++)
|
|
, m_delay(delay)
|
|
, m_at(get_monotonic_time_ms() + delay)
|
|
, m_rv(*pRv)
|
|
{
|
|
}
|
|
|
|
int32_t delay() const
|
|
{
|
|
return m_delay;
|
|
}
|
|
|
|
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);
|
|
|
|
cout << m_id << ": " << diff << endl;
|
|
|
|
if (diff > 50)
|
|
{
|
|
cout << "Error: Difference between expected and happened > 50: " << diff << endl;
|
|
m_rv = EXIT_FAILURE;
|
|
}
|
|
|
|
m_at += m_delay;
|
|
|
|
if (--s_ticks < 0)
|
|
{
|
|
maxscale::Worker::shutdown_all();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private:
|
|
static int s_id;
|
|
|
|
int m_id;
|
|
int32_t m_delay;
|
|
int64_t m_at;
|
|
int& m_rv;
|
|
};
|
|
|
|
int TimerTest::s_id = 1;
|
|
int TimerTest::s_ticks;
|
|
|
|
int run()
|
|
{
|
|
int rv = EXIT_SUCCESS;
|
|
|
|
TimerTest::s_ticks = 100;
|
|
|
|
TestWorker w;
|
|
|
|
TimerTest t1(&rv, 200);
|
|
TimerTest t2(&rv, 300);
|
|
TimerTest t3(&rv, 400);
|
|
TimerTest t4(&rv, 500);
|
|
TimerTest t5(&rv, 600);
|
|
|
|
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();
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
}
|
|
|
|
int main()
|
|
{
|
|
int rv = EXIT_FAILURE;
|
|
|
|
if (mxs_log_init(NULL, NULL, MXS_LOG_TARGET_STDOUT))
|
|
{
|
|
poll_init();
|
|
maxscale::MessageQueue::init();
|
|
maxscale::Worker::init();
|
|
|
|
rv = run();
|
|
|
|
mxs_log_finish();
|
|
}
|
|
|
|
return rv;
|
|
}
|