Periodically refresh read transaction inside hinted scheduler (#4325)

This commit is contained in:
Piotr Wójcik 2023-11-03 16:16:55 +01:00 committed by GitHub
commit 0377c4f97c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 5 deletions

View file

@ -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<nano::block_hash> 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 ())
{

View file

@ -3,6 +3,7 @@
#include <nano/lib/locks.hpp>
#include <nano/lib/numbers.hpp>
#include <nano/secure/common.hpp>
#include <nano/store/transaction.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
@ -61,7 +62,7 @@ private:
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;

View file

@ -36,6 +36,7 @@ nano::store::write_transaction_impl::write_transaction_impl (nano::id_dispenser:
nano::store::read_transaction::read_transaction (std::unique_ptr<store::read_transaction_impl> 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_ptr<store::write_
* For IO threads, we do not want them to block on creating write transactions.
*/
debug_assert (nano::thread_role::get () != nano::thread_role::name::io);
start = std::chrono::steady_clock::now ();
}
void * nano::store::write_transaction::get_handle () const
@ -95,12 +108,22 @@ void nano::store::write_transaction::commit ()
void nano::store::write_transaction::renew ()
{
impl->renew ();
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

View file

@ -56,9 +56,11 @@ public:
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<read_transaction_impl> impl;
mutable std::chrono::steady_clock::time_point start;
};
/**
@ -75,9 +77,11 @@ public:
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<write_transaction_impl> impl;
std::chrono::steady_clock::time_point start;
};
} // namespace nano::store