Add start & stop to election_scheduler (#4090)

This commit is contained in:
Piotr Wójcik 2023-02-01 12:20:08 +01:00 committed by GitHub
commit c75f04fcf1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 69 additions and 46 deletions

View file

@ -2,16 +2,34 @@
#include <nano/node/node.hpp>
nano::election_scheduler::election_scheduler (nano::node & node) :
node{ node },
stopped{ false },
thread{ [this] () { run (); } }
node{ node }
{
}
nano::election_scheduler::~election_scheduler ()
{
stop ();
thread.join ();
// Thread must be stopped before destruction
debug_assert (!thread.joinable ());
}
void nano::election_scheduler::start ()
{
debug_assert (!thread.joinable ());
thread = std::thread{ [this] () {
nano::thread_role::set (nano::thread_role::name::election_scheduler);
run ();
} };
}
void nano::election_scheduler::stop ()
{
{
nano::lock_guard<nano::mutex> lock{ mutex };
stopped = true;
}
notify ();
nano::join_or_pass (thread);
}
void nano::election_scheduler::manual (std::shared_ptr<nano::block> const & block_a, boost::optional<nano::uint128_t> const & previous_balance_a, nano::election_behavior election_behavior_a, std::function<void (std::shared_ptr<nano::block> const &)> const & confirmation_action_a)
@ -49,13 +67,6 @@ bool nano::election_scheduler::activate (nano::account const & account_a, nano::
return false; // Not activated
}
void nano::election_scheduler::stop ()
{
nano::unique_lock<nano::mutex> lock{ mutex };
stopped = true;
notify ();
}
void nano::election_scheduler::flush ()
{
nano::unique_lock<nano::mutex> lock{ mutex };
@ -113,7 +124,6 @@ bool nano::election_scheduler::overfill_predicate () const
void nano::election_scheduler::run ()
{
nano::thread_role::set (nano::thread_role::name::election_scheduler);
nano::unique_lock<nano::mutex> lock{ mutex };
while (!stopped)
{

View file

@ -15,11 +15,16 @@ namespace nano
{
class block;
class node;
class election_scheduler final
{
public:
election_scheduler (nano::node & node);
election_scheduler (nano::node &);
~election_scheduler ();
void start ();
void stop ();
// Manualy start an election for a block
// Call action with confirmed block, may be different than what we started with
void manual (std::shared_ptr<nano::block> const &, boost::optional<nano::uint128_t> const & = boost::none, nano::election_behavior = nano::election_behavior::normal, std::function<void (std::shared_ptr<nano::block> const &)> const & = nullptr);
@ -28,7 +33,6 @@ public:
* @return true if account was activated
*/
bool activate (nano::account const &, nano::transaction const &);
void stop ();
// Blocks until no more elections can be activated or there are no more elections to activate
void flush ();
void notify ();
@ -37,16 +41,20 @@ public:
std::size_t priority_queue_size () const;
std::unique_ptr<container_info_component> collect_container_info (std::string const &);
private: // Dependencies
nano::node & node;
private:
void run ();
bool empty_locked () const;
bool priority_queue_predicate () const;
bool manual_queue_predicate () const;
bool overfill_predicate () const;
nano::prioritization priority;
std::deque<std::tuple<std::shared_ptr<nano::block>, boost::optional<nano::uint128_t>, nano::election_behavior, std::function<void (std::shared_ptr<nano::block>)>>> manual_queue;
nano::node & node;
bool stopped;
bool stopped{ false };
nano::condition_variable condition;
mutable nano::mutex mutex;
std::thread thread;

View file

@ -696,6 +696,7 @@ void nano::node::start ()
active.start ();
generator.start ();
final_generator.start ();
scheduler.start ();
backlog.start ();
hinting.start ();
bootstrap_server.start ();
@ -704,37 +705,41 @@ void nano::node::start ()
void nano::node::stop ()
{
if (!stopped.exchange (true))
// Ensure stop can only be called once
if (stopped.exchange (true))
{
logger.always_log ("Node stopping");
// Cancels ongoing work generation tasks, which may be blocking other threads
// No tasks may wait for work generation in I/O threads, or termination signal capturing will be unable to call node::stop()
distributed_work.stop ();
backlog.stop ();
unchecked.stop ();
block_processor.stop ();
aggregator.stop ();
vote_processor.stop ();
scheduler.stop ();
hinting.stop ();
active.stop ();
generator.stop ();
final_generator.stop ();
confirmation_height_processor.stop ();
network.stop ();
telemetry->stop ();
websocket.stop ();
bootstrap_server.stop ();
bootstrap_initiator.stop ();
tcp_listener.stop ();
port_mapping.stop ();
checker.stop ();
wallets.stop ();
stats.stop ();
epoch_upgrader.stop ();
workers.stop ();
// work pool is not stopped on purpose due to testing setup
return;
}
logger.always_log ("Node stopping");
// Cancels ongoing work generation tasks, which may be blocking other threads
// No tasks may wait for work generation in I/O threads, or termination signal capturing will be unable to call node::stop()
distributed_work.stop ();
backlog.stop ();
unchecked.stop ();
block_processor.stop ();
aggregator.stop ();
vote_processor.stop ();
scheduler.stop ();
hinting.stop ();
active.stop ();
generator.stop ();
final_generator.stop ();
confirmation_height_processor.stop ();
network.stop ();
telemetry->stop ();
websocket.stop ();
bootstrap_server.stop ();
bootstrap_initiator.stop ();
tcp_listener.stop ();
port_mapping.stop ();
checker.stop ();
wallets.stop ();
stats.stop ();
epoch_upgrader.stop ();
workers.stop ();
// work pool is not stopped on purpose due to testing setup
}
void nano::node::keepalive_preconfigured (std::vector<std::string> const & peers_a)