MXS-1754 Add delayed calling to Worker
It's now possible to provide Worker with a function to call at a later time. It's possible to provide a function or a member function (with the object), taking zero or one argument of any kind. The argument must be copyable. There's currently no way to cancel a call, which must be added as typically the delayed calling is associated with a session and if the session is closed before the delayed call is made, bad things are likely to happen.
This commit is contained in:
@ -27,6 +27,7 @@ add_executable(test_trxtracking test_trxtracking.cc)
|
||||
add_executable(test_users test_users.cc)
|
||||
add_executable(test_utils test_utils.cc)
|
||||
add_executable(test_session_track test_session_track.cc)
|
||||
add_executable(test_worker test_worker.cc)
|
||||
|
||||
target_link_libraries(profile_trxboundaryparser maxscale-common)
|
||||
target_link_libraries(test_adminusers maxscale-common)
|
||||
@ -57,6 +58,7 @@ target_link_libraries(test_trxtracking maxscale-common)
|
||||
target_link_libraries(test_users maxscale-common)
|
||||
target_link_libraries(test_utils maxscale-common)
|
||||
target_link_libraries(test_session_track mysqlcommon)
|
||||
target_link_libraries(test_worker maxscale-common)
|
||||
|
||||
add_test(test_adminusers test_adminusers)
|
||||
add_test(test_atomic test_atomic)
|
||||
@ -93,6 +95,7 @@ add_test(test_trxtracking test_trxtracking)
|
||||
add_test(test_users test_users)
|
||||
add_test(test_utils test_utils)
|
||||
add_test(test_session_track test_session_track)
|
||||
add_test(test_worker test_worker)
|
||||
|
||||
add_subdirectory(rest-api)
|
||||
add_subdirectory(canonical_tests)
|
||||
|
||||
159
server/core/test/test_worker.cc
Normal file
159
server/core/test/test_worker.cc
Normal file
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* 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()
|
||||
{
|
||||
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(), &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.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;
|
||||
}
|
||||
Reference in New Issue
Block a user