diff --git a/nano/node/scheduler/hinted.cpp b/nano/node/scheduler/hinted.cpp index 13a36d91bd..54f5bdf7b8 100644 --- a/nano/node/scheduler/hinted.cpp +++ b/nano/node/scheduler/hinted.cpp @@ -59,13 +59,15 @@ bool nano::scheduler::hinted::predicate () const return active.vacancy (nano::election_behavior::hinted) > 0; } -void nano::scheduler::hinted::activate (const nano::store::transaction & transaction, const nano::block_hash & hash, bool check_dependents) +void nano::scheduler::hinted::activate (const nano::store::read_transaction & transaction, const nano::block_hash & hash, bool check_dependents) { std::stack stack; stack.push (hash); while (!stack.empty ()) { + transaction.refresh_if_needed (); + const nano::block_hash current_hash = stack.top (); stack.pop (); @@ -115,9 +117,12 @@ void nano::scheduler::hinted::run_iterative () const auto minimum_tally = tally_threshold (); const auto minimum_final_tally = final_tally_threshold (); + // Get the list before db transaction starts to avoid unnecessary slowdowns + auto tops = vote_cache.top (minimum_tally); + auto transaction = node.store.tx_begin_read (); - for (auto const & entry : vote_cache.top (minimum_tally)) + for (auto const & entry : tops) { if (!predicate ()) { diff --git a/nano/node/scheduler/hinted.hpp b/nano/node/scheduler/hinted.hpp index a18d11dcb8..590697c39f 100644 --- a/nano/node/scheduler/hinted.hpp +++ b/nano/node/scheduler/hinted.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -61,7 +62,7 @@ class hinted final bool predicate () const; void run (); void run_iterative (); - void activate (nano::store::transaction const &, nano::block_hash const & hash, bool check_dependents); + void activate (nano::store::read_transaction const &, nano::block_hash const & hash, bool check_dependents); nano::uint128_t tally_threshold () const; nano::uint128_t final_tally_threshold () const; diff --git a/nano/store/transaction.cpp b/nano/store/transaction.cpp index 395f81caf9..4cbc57e460 100644 --- a/nano/store/transaction.cpp +++ b/nano/store/transaction.cpp @@ -36,6 +36,7 @@ nano::store::write_transaction_impl::write_transaction_impl (nano::id_dispenser: nano::store::read_transaction::read_transaction (std::unique_ptr read_transaction_impl) : impl (std::move (read_transaction_impl)) { + start = std::chrono::steady_clock::now (); } void * nano::store::read_transaction::get_handle () const @@ -56,6 +57,7 @@ void nano::store::read_transaction::reset () const void nano::store::read_transaction::renew () const { impl->renew (); + start = std::chrono::steady_clock::now (); } void nano::store::read_transaction::refresh () const @@ -64,6 +66,15 @@ void nano::store::read_transaction::refresh () const renew (); } +void nano::store::read_transaction::refresh_if_needed (std::chrono::milliseconds max_age) const +{ + auto now = std::chrono::steady_clock::now (); + if (now - start > max_age) + { + refresh (); + } +} + /* * write_transaction */ @@ -75,6 +86,8 @@ nano::store::write_transaction::write_transaction (std::unique_ptrrenew (); + start = std::chrono::steady_clock::now (); } void nano::store::write_transaction::refresh () { - impl->commit (); - impl->renew (); + commit (); + renew (); +} + +void nano::store::write_transaction::refresh_if_needed (std::chrono::milliseconds max_age) +{ + auto now = std::chrono::steady_clock::now (); + if (now - start > max_age) + { + refresh (); + } } bool nano::store::write_transaction::contains (nano::tables table_a) const diff --git a/nano/store/transaction.hpp b/nano/store/transaction.hpp index 70b2d9c344..042b42bb59 100644 --- a/nano/store/transaction.hpp +++ b/nano/store/transaction.hpp @@ -56,9 +56,11 @@ class read_transaction final : public transaction void reset () const; void renew () const; void refresh () const; + void refresh_if_needed (std::chrono::milliseconds max_age = std::chrono::milliseconds{ 500 }) const; private: std::unique_ptr impl; + mutable std::chrono::steady_clock::time_point start; }; /** @@ -75,9 +77,11 @@ class write_transaction final : public transaction void commit (); void renew (); void refresh (); + void refresh_if_needed (std::chrono::milliseconds max_age = std::chrono::milliseconds{ 500 }); bool contains (nano::tables table_a) const; private: std::unique_ptr impl; + std::chrono::steady_clock::time_point start; }; } // namespace nano::store