-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Move get_info off main thread and run in http thread #920
Merged
+308
−103
Merged
Changes from all commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
ab2510a
create get_info_db for caching get_info results
linh2931 247e9a5
Use get_info_db to return the data for get_info
linh2931 3c15c13
Update tests for compiling
linh2931 2ab5dcb
Update files to use get_info_db::get_info_results
linh2931 28f4f18
Move get_info off main thread
linh2931 549bc55
Check if chain head and forkdb root are valid before use them
linh2931 b9226e6
add const specifier to get_info_enabled as it cannot be changed after…
linh2931 f43bf48
Move rw_mutex above cached_results which is what it protects for
linh2931 ec75c3f
Set constant values (chain_id, version_hex, version_string, and full_…
linh2931 5309d0d
Move itoh to FC hex.hpp
linh2931 6eb1324
Add handling irreversible_block signal and refactor to make it more e…
linh2931 d6a4d6d
Need to store all information on on_irreversible_block so it is in sync
linh2931 9cd5f22
Fill in actual block info for on_irreversible_block
linh2931 0cca888
Merge branch 'main' into get_info_off_main_thread
linh2931 f7cdc5d
Fix a merge conflict from main
linh2931 d1655be
Reimplement the main algorithm mutex free
linh2931 be24dce
Pre-compute fixed data
linh2931 cc9e89e
Add is_valid() function for code clarity
linh2931 44c7a9a
Merge branch 'main' into get_info_off_main_thread
linh2931 b2213aa
Rename is_valid() to contains_full_data() and move it to get_info_res…
linh2931 2f27f49
remove unused include <shared_mutex>
linh2931 ee913fa
Grab fork_db_root once to avoid multiple mutexes in fork db
linh2931 11f92c2
add const to contains_full_data()
linh2931 a2f18a2
Call fork_db_has_root() only once to avoid an extra mutex in fork db
linh2931 8d8da68
Merge branch 'main' into get_info_off_main_thread
linh2931 20e3140
Do not call fork_db_has_root() explicitly to save one mutex lock in f…
linh2931 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
#include <eosio/chain_plugin/get_info_db.hpp> | ||
#include <eosio/chain/resource_limits.hpp> | ||
#include <eosio/chain/application.hpp> | ||
|
||
using namespace eosio; | ||
using namespace eosio::chain; | ||
using namespace appbase; | ||
|
||
namespace eosio::chain_apis { | ||
/** | ||
* Implementation details of the get_info results | ||
*/ | ||
struct get_info_db_impl { | ||
get_info_db_impl(const chain::controller& controller, bool get_info_enabled) | ||
: controller(controller) | ||
, get_info_enabled(get_info_enabled) | ||
, server_version(fc::itoh(static_cast<uint32_t>(app().version()))) | ||
, chain_id(controller.get_chain_id()) | ||
, server_version_string(app().version_string()) | ||
, server_full_version_string(app().full_version_string()) {} | ||
|
||
// Called on accepted_block signal. | ||
void on_accepted_block() { | ||
try { | ||
if (!get_info_enabled) { | ||
return; | ||
} | ||
|
||
store_info(); | ||
} FC_LOG_AND_DROP(("get_info_db_impl on_accepted_block ERROR")); | ||
} | ||
|
||
// Called on irreversible_block signal. | ||
void on_irreversible_block(const chain::signed_block_ptr& block, const block_id_type& id) { | ||
try { | ||
if (!get_info_enabled) { | ||
return; | ||
} | ||
|
||
store_info(block, id); | ||
} FC_LOG_AND_DROP(("get_info_db_impl on_irreversible_block ERROR")); | ||
} | ||
|
||
// Returns cached get_info results | ||
get_info_db::get_info_results get_info() { | ||
// safely load the info_cache pointer | ||
std::shared_ptr<get_info_db::get_info_results> info = std::atomic_load(&info_cache); | ||
|
||
if (info && info->contains_full_data()) { | ||
return *info; | ||
} | ||
|
||
// This only happens right after initialization when starts from | ||
// snapshot as no signals are emitted. We need to cache the current states. | ||
store_info(); | ||
|
||
info = std::atomic_load(&info_cache); | ||
assert(info); | ||
return *info; | ||
} | ||
|
||
private: | ||
// A handle to the controller. | ||
const chain::controller& controller; | ||
|
||
// Indication whether get_info RPC is enabled. | ||
const bool get_info_enabled = false; | ||
|
||
// Cache to store the current get_info results. | ||
// Using std::atomic_load and std::atomic_store to switch pointers. | ||
std::shared_ptr<get_info_db::get_info_results> info_cache = nullptr; | ||
|
||
// Fixed data | ||
std::string server_version; | ||
chain::chain_id_type chain_id; | ||
std::string server_version_string; | ||
std::string server_full_version_string; | ||
|
||
// Stores common data, and returns fork_db_has_root for future uses to avoid | ||
// multiple mutexes in fork db. | ||
bool store_info_common(const std::shared_ptr<get_info_db::get_info_results>& info) { | ||
assert(info); | ||
|
||
// fixed part | ||
info->server_version = server_version; | ||
info->chain_id = chain_id; | ||
info->server_version_string = server_version_string; | ||
info->server_full_version_string = server_full_version_string; | ||
|
||
// chain head part | ||
const auto& head = controller.head(); | ||
if (head.is_valid()) { | ||
info->head_block_id = head.id(); | ||
info->head_block_num = block_header::num_from_id(info->head_block_id); | ||
info->head_block_time = head.block_time(); | ||
info->head_block_producer = head.producer(); | ||
} | ||
|
||
// fork_db part | ||
const auto& fork_db_head = controller.fork_db_head(); | ||
bool fork_db_has_root = fork_db_head.is_valid(); // a valid head implies fork_db has root | ||
if (fork_db_has_root) { | ||
info->fork_db_head_block_id = fork_db_head.id(); | ||
info->fork_db_head_block_num = block_header::num_from_id(*info->fork_db_head_block_id); | ||
info->earliest_available_block_num = controller.earliest_available_block_num(); | ||
} | ||
|
||
// resource_limits | ||
const auto& rm = controller.get_resource_limits_manager(); | ||
info->virtual_block_cpu_limit = rm.get_virtual_block_cpu_limit(); | ||
info->virtual_block_net_limit = rm.get_virtual_block_net_limit(); | ||
info->block_cpu_limit = rm.get_block_cpu_limit(); | ||
info->block_net_limit = rm.get_block_net_limit(); | ||
info->total_cpu_weight = rm.get_total_cpu_weight(); | ||
info->total_net_weight = rm.get_total_net_weight(); | ||
|
||
return fork_db_has_root; | ||
} | ||
|
||
void store_info() { | ||
std::shared_ptr<get_info_db::get_info_results> info = std::make_shared<get_info_db::get_info_results>(); | ||
|
||
bool fork_db_has_root = store_info_common(info); // store_info_common returns fork_db_has_root to avoid mutex in fork db in call to controller.fork_db_has_root() | ||
|
||
if (fork_db_has_root) { | ||
const auto& root = controller.fork_db_root(); // avoid multiple mutexes in fork db | ||
info->last_irreversible_block_id = root.id(); | ||
info->last_irreversible_block_num = block_header::num_from_id(info->last_irreversible_block_id); | ||
info->last_irreversible_block_time = root.block_time(); | ||
} | ||
|
||
std::atomic_store(&info_cache, info); // replace current cache safely | ||
} | ||
|
||
void store_info(const chain::signed_block_ptr& block, const block_id_type& id) { | ||
std::shared_ptr<get_info_db::get_info_results> info = std::make_shared<get_info_db::get_info_results>(); | ||
|
||
store_info_common(info); | ||
|
||
info->last_irreversible_block_id = id; | ||
info->last_irreversible_block_num = block_header::num_from_id(info->last_irreversible_block_id); | ||
info->last_irreversible_block_time = block->timestamp; | ||
|
||
std::atomic_store(&info_cache, info); // replace current cache safely | ||
greg7mdp marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
}; // get_info_db_impl | ||
|
||
get_info_db::get_info_db( const chain::controller& controller, bool get_info_enabled ) | ||
:_impl(std::make_unique<get_info_db_impl>(controller, get_info_enabled)) {} | ||
|
||
get_info_db::~get_info_db() = default; | ||
|
||
void get_info_db::on_accepted_block() { | ||
_impl->on_accepted_block(); | ||
} | ||
|
||
void get_info_db::on_irreversible_block(const chain::signed_block_ptr& block, const block_id_type& id) { | ||
_impl->on_irreversible_block(block, id); | ||
} | ||
|
||
get_info_db::get_info_results get_info_db::get_info() const { | ||
return _impl->get_info(); | ||
} | ||
} // namespace eosio::chain_apis |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We agreed that we didn't need that check since
chain_api_plugin
is most of the time configured.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is most likely configured in BP nodes but not necessarily in other nodes.