diff --git a/nano/node/active_transactions.cpp b/nano/node/active_transactions.cpp index 59171c5f..eaa94785 100644 --- a/nano/node/active_transactions.cpp +++ b/nano/node/active_transactions.cpp @@ -341,17 +341,25 @@ void nano::active_transactions::request_loop () while (!stopped && !node.flags.disable_request_loop) { - // Account for the time spent in request_confirm by defining the wakeup point beforehand - const auto wakeup_l (std::chrono::steady_clock::now () + std::chrono::milliseconds (node.network_params.network.request_interval_ms)); + // If many votes are queued, ensure at least the currently active ones finish processing + lock.unlock (); + if (node.vote_processor.half_full ()) + { + node.vote_processor.flush_active (); + } + lock.lock (); + + const auto stamp_l = std::chrono::steady_clock::now (); // frontiers_confirmation should be above update_active_multiplier to ensure new sorted roots are updated frontiers_confirmation (lock); update_active_multiplier (lock); request_confirm (lock); - // Sleep until all broadcasts are done, plus the remaining loop time if (!stopped) { + constexpr auto min_sleep_l = std::chrono::milliseconds (250); + const auto wakeup_l = std::max (stamp_l + std::chrono::milliseconds (node.network_params.network.request_interval_ms), std::chrono::steady_clock::now () + min_sleep_l); condition.wait_until (lock, wakeup_l, [&wakeup_l, &stopped = stopped] { return stopped || std::chrono::steady_clock::now () >= wakeup_l; }); } } diff --git a/nano/node/vote_processor.cpp b/nano/node/vote_processor.cpp index 8b8b38d5..c76cd8f6 100644 --- a/nano/node/vote_processor.cpp +++ b/nano/node/vote_processor.cpp @@ -222,6 +222,15 @@ void nano::vote_processor::flush () } } +void nano::vote_processor::flush_active () +{ + nano::unique_lock lock (mutex); + while (is_active) + { + condition.wait (lock); + } +} + size_t nano::vote_processor::size () { nano::lock_guard guard (mutex); @@ -234,6 +243,11 @@ bool nano::vote_processor::empty () return votes.empty (); } +bool nano::vote_processor::half_full () +{ + return size () >= max_votes / 2; +} + void nano::vote_processor::calculate_weights () { nano::unique_lock lock (mutex); diff --git a/nano/node/vote_processor.hpp b/nano/node/vote_processor.hpp index a0d0577c..0bb27918 100644 --- a/nano/node/vote_processor.hpp +++ b/nano/node/vote_processor.hpp @@ -40,8 +40,11 @@ public: nano::vote_code vote_blocking (std::shared_ptr, std::shared_ptr, bool = false); void verify_votes (std::deque, std::shared_ptr>> const &); void flush (); + /** Block until the currently active processing cycle finishes */ + void flush_active (); size_t size (); bool empty (); + bool half_full (); void calculate_weights (); void stop ();