Files
scylladb/test/raft/ticker.hh
Kamil Braun e5fc0681d9 test: raft: randomized_nemesis_test: ping all shards on each tick
Right now the test is running entirely on shard 0, but we want to
introduce a sharded service to the test. The initial naive attempt of
doing that failed because the test would time out (reach the tick limit)
before any work distributed to other shards could even start. The
solution in this commit solves that by synchronizing the shards on each
tick.

When the test is ran with smp=1, the behavior is as before.
2022-05-09 13:14:41 +02:00

64 lines
1.6 KiB
C++

/*
* Copyright (C) 2021 ScyllaDB
*/
/*
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#pragma once
#include <seastar/core/reactor.hh>
#include <seastar/core/coroutine.hh>
#include <seastar/core/future-util.hh>
using namespace seastar;
// Calls the given function as fast as the Seastar reactor allows and waits on each call.
// The function is passed an incrementing integer (incremented by one for each call, starting at 0).
// The number of ticks can be limited. We crash if the ticker reaches the limit before it's `abort()`ed.
// Call `start()` to start the ticking.
class ticker {
bool _stop = false;
std::optional<future<>> _ticker;
seastar::logger& _logger;
public:
ticker(seastar::logger& l) : _logger(l) {}
ticker(const ticker&) = delete;
ticker(ticker&&) = delete;
~ticker() {
assert(!_ticker);
}
using on_tick_t = noncopyable_function<future<>(uint64_t)>;
void start(on_tick_t fun, uint64_t limit = std::numeric_limits<uint64_t>::max()) {
assert(!_ticker);
_ticker = tick(std::move(fun), limit);
}
future<> abort() {
if (_ticker) {
_stop = true;
co_await *std::exchange(_ticker, std::nullopt);
}
}
private:
future<> tick(on_tick_t fun, uint64_t limit) {
for (uint64_t tick = 0; tick < limit; ++tick) {
if (_stop) {
_logger.info("ticker: finishing after {} ticks", tick);
co_return;
}
co_await fun(tick);
}
_logger.error("ticker: limit reached");
assert(false);
}
};