From 12ab91c6443d432fdcb64fec79e94a481dad8e3e Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Thu, 7 Mar 2019 15:04:07 -0500 Subject: [PATCH 1/2] Move json::to_string processing to http thread pool --- plugins/http_plugin/http_plugin.cpp | 32 ++++++++++--------- .../include/eosio/http_plugin/http_plugin.hpp | 2 +- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/plugins/http_plugin/http_plugin.cpp b/plugins/http_plugin/http_plugin.cpp index 3bb5b530d5f..7e205736874 100644 --- a/plugins/http_plugin/http_plugin.cpp +++ b/plugins/http_plugin/http_plugin.cpp @@ -304,18 +304,20 @@ namespace eosio { [ioc = this->server_ioc, &bytes_in_flight = this->bytes_in_flight, handler_itr, resource{std::move( resource )}, body{std::move( body )}, con]() { try { - bytes_in_flight -= body.size(); handler_itr->second( resource, body, - [ioc{std::move(ioc)}, &bytes_in_flight, con]( int code, std::string response_body ) { - bytes_in_flight += response_body.size(); - boost::asio::post( *ioc, [ioc, response_body{std::move( response_body )}, &bytes_in_flight, con, code]() { - size_t body_size = response_body.size(); - con->set_body( std::move( response_body ) ); + [ioc{std::move(ioc)}, &bytes_in_flight, con]( int code, fc::variant response_body ) { + boost::asio::post( *ioc, [ioc, response_body{std::move( response_body )}, &bytes_in_flight, con, code]() mutable { + std::string json = fc::json::to_string( response_body ); + response_body.clear(); + const size_t json_size = json.size(); + bytes_in_flight += json_size; + con->set_body( std::move( json ) ); con->set_status( websocketpp::http::status_code::value( code ) ); con->send_http_response(); - bytes_in_flight -= body_size; + bytes_in_flight -= json_size; } ); }); + bytes_in_flight -= body.size(); } catch( ... ) { handle_exception( con ); con->send_http_response(); @@ -592,7 +594,7 @@ namespace eosio { try { if (body.empty()) body = "{}"; auto result = (*this).get_supported_apis(); - cb(200, fc::json::to_string(result)); + cb(200, fc::variant(result)); } catch (...) { handle_exception("node", "get_supported_apis", body, cb); } @@ -629,21 +631,21 @@ namespace eosio { throw; } catch (chain::unknown_block_exception& e) { error_results results{400, "Unknown Block", error_results::error_info(e, verbose_http_errors)}; - cb( 400, fc::json::to_string( results )); + cb( 400, fc::variant( results )); } catch (chain::unsatisfied_authorization& e) { error_results results{401, "UnAuthorized", error_results::error_info(e, verbose_http_errors)}; - cb( 401, fc::json::to_string( results )); + cb( 401, fc::variant( results )); } catch (chain::tx_duplicate& e) { error_results results{409, "Conflict", error_results::error_info(e, verbose_http_errors)}; - cb( 409, fc::json::to_string( results )); + cb( 409, fc::variant( results )); } catch (fc::eof_exception& e) { error_results results{422, "Unprocessable Entity", error_results::error_info(e, verbose_http_errors)}; - cb( 422, fc::json::to_string( results )); + cb( 422, fc::variant( results )); elog( "Unable to parse arguments to ${api}.${call}", ("api", api_name)( "call", call_name )); dlog("Bad arguments: ${args}", ("args", body)); } catch (fc::exception& e) { error_results results{500, "Internal Service Error", error_results::error_info(e, verbose_http_errors)}; - cb( 500, fc::json::to_string( results )); + cb( 500, fc::variant( results )); if (e.code() != chain::greylist_net_usage_exceeded::code_value && e.code() != chain::greylist_cpu_usage_exceeded::code_value) { elog( "FC Exception encountered while processing ${api}.${call}", ("api", api_name)( "call", call_name )); @@ -651,14 +653,14 @@ namespace eosio { } } catch (std::exception& e) { error_results results{500, "Internal Service Error", error_results::error_info(fc::exception( FC_LOG_MESSAGE( error, e.what())), verbose_http_errors)}; - cb( 500, fc::json::to_string( results )); + cb( 500, fc::variant( results )); elog( "STD Exception encountered while processing ${api}.${call}", ("api", api_name)( "call", call_name )); dlog( "Exception Details: ${e}", ("e", e.what())); } catch (...) { error_results results{500, "Internal Service Error", error_results::error_info(fc::exception( FC_LOG_MESSAGE( error, "Unknown Exception" )), verbose_http_errors)}; - cb( 500, fc::json::to_string( results )); + cb( 500, fc::variant( results )); elog( "Unknown Exception encountered while processing ${api}.${call}", ("api", api_name)( "call", call_name )); } diff --git a/plugins/http_plugin/include/eosio/http_plugin/http_plugin.hpp b/plugins/http_plugin/include/eosio/http_plugin/http_plugin.hpp index a522b2b1739..eaa132ce0e4 100644 --- a/plugins/http_plugin/include/eosio/http_plugin/http_plugin.hpp +++ b/plugins/http_plugin/include/eosio/http_plugin/http_plugin.hpp @@ -17,7 +17,7 @@ namespace eosio { * * Arguments: response_code, response_body */ - using url_response_callback = std::function; + using url_response_callback = std::function; /** * @brief Callback type for a URL handler From 97b385cf0303c7ad86fb1e45289bad2124745d56 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Thu, 7 Mar 2019 15:05:35 -0500 Subject: [PATCH 2/2] Move json::to_string to http thread pool --- plugins/chain_api_plugin/chain_api_plugin.cpp | 10 +++++----- plugins/db_size_api_plugin/db_size_api_plugin.cpp | 2 +- .../faucet_testnet_plugin/faucet_testnet_plugin.cpp | 2 +- plugins/history_api_plugin/history_api_plugin.cpp | 4 ++-- plugins/login_plugin/login_plugin.cpp | 4 ++-- plugins/net_api_plugin/net_api_plugin.cpp | 2 +- plugins/producer_api_plugin/producer_api_plugin.cpp | 2 +- .../test_control_api_plugin.cpp | 4 ++-- plugins/txn_test_gen_plugin/txn_test_gen_plugin.cpp | 4 ++-- plugins/wallet_api_plugin/wallet_api_plugin.cpp | 2 +- programs/keosd/main.cpp | 2 +- 11 files changed, 19 insertions(+), 19 deletions(-) diff --git a/plugins/chain_api_plugin/chain_api_plugin.cpp b/plugins/chain_api_plugin/chain_api_plugin.cpp index 8b9fd3f843c..8243765783d 100644 --- a/plugins/chain_api_plugin/chain_api_plugin.cpp +++ b/plugins/chain_api_plugin/chain_api_plugin.cpp @@ -28,10 +28,10 @@ chain_api_plugin::~chain_api_plugin(){} void chain_api_plugin::set_program_options(options_description&, options_description&) {} void chain_api_plugin::plugin_initialize(const variables_map&) {} -struct async_result_visitor : public fc::visitor { +struct async_result_visitor : public fc::visitor { template - std::string operator()(const T& v) const { - return fc::json::to_string(v); + fc::variant operator()(const T& v) const { + return fc::variant(v); } }; @@ -41,8 +41,8 @@ struct async_result_visitor : public fc::visitor { api_handle.validate(); \ try { \ if (body.empty()) body = "{}"; \ - auto result = api_handle.call_name(fc::json::from_string(body).as()); \ - cb(http_response_code, fc::json::to_string(result)); \ + fc::variant result( api_handle.call_name(fc::json::from_string(body).as()) ); \ + cb(http_response_code, std::move(result)); \ } catch (...) { \ http_plugin::handle_exception(#api_name, #call_name, body, cb); \ } \ diff --git a/plugins/db_size_api_plugin/db_size_api_plugin.cpp b/plugins/db_size_api_plugin/db_size_api_plugin.cpp index 8eed8b388ed..8c6df9566fe 100644 --- a/plugins/db_size_api_plugin/db_size_api_plugin.cpp +++ b/plugins/db_size_api_plugin/db_size_api_plugin.cpp @@ -18,7 +18,7 @@ using namespace eosio; try { \ if (body.empty()) body = "{}"; \ INVOKE \ - cb(http_response_code, fc::json::to_string(result)); \ + cb(http_response_code, fc::variant(result)); \ } catch (...) { \ http_plugin::handle_exception(#api_name, #call_name, body, cb); \ } \ diff --git a/plugins/faucet_testnet_plugin/faucet_testnet_plugin.cpp b/plugins/faucet_testnet_plugin/faucet_testnet_plugin.cpp index d6f8f53e7b3..32db7146f6d 100644 --- a/plugins/faucet_testnet_plugin/faucet_testnet_plugin.cpp +++ b/plugins/faucet_testnet_plugin/faucet_testnet_plugin.cpp @@ -60,7 +60,7 @@ using results_pair = std::pair; try { \ if (body.empty()) body = "{}"; \ const auto result = api_handle->invoke_cb(body); \ - response_cb(result.first, fc::json::to_string(result.second)); \ + response_cb(result.first, fc::variant(result.second)); \ } catch (...) { \ http_plugin::handle_exception(#api_name, #call_name, body, response_cb); \ } \ diff --git a/plugins/history_api_plugin/history_api_plugin.cpp b/plugins/history_api_plugin/history_api_plugin.cpp index f9030d8c91c..d76dd7fd44b 100644 --- a/plugins/history_api_plugin/history_api_plugin.cpp +++ b/plugins/history_api_plugin/history_api_plugin.cpp @@ -24,8 +24,8 @@ void history_api_plugin::plugin_initialize(const variables_map&) {} [api_handle](string, string body, url_response_callback cb) mutable { \ try { \ if (body.empty()) body = "{}"; \ - auto result = api_handle.call_name(fc::json::from_string(body).as()); \ - cb(200, fc::json::to_string(result)); \ + fc::variant result( api_handle.call_name(fc::json::from_string(body).as()) ); \ + cb(200, std::move(result)); \ } catch (...) { \ http_plugin::handle_exception(#api_name, #call_name, body, cb); \ } \ diff --git a/plugins/login_plugin/login_plugin.cpp b/plugins/login_plugin/login_plugin.cpp index 0aeac67dce4..374a04b25dc 100644 --- a/plugins/login_plugin/login_plugin.cpp +++ b/plugins/login_plugin/login_plugin.cpp @@ -68,8 +68,8 @@ void login_plugin::plugin_initialize(const variables_map& options) { try { \ if (body.empty()) \ body = "{}"; \ - auto result = call_name(fc::json::from_string(body).as()); \ - cb(http_response_code, fc::json::to_string(result)); \ + fc::variant result( call_name(fc::json::from_string(body).as()) ); \ + cb(http_response_code, std::move(result)); \ } catch (...) { \ http_plugin::handle_exception("login", #call_name, body, cb); \ } \ diff --git a/plugins/net_api_plugin/net_api_plugin.cpp b/plugins/net_api_plugin/net_api_plugin.cpp index 3b7327c4313..315ea2816e9 100644 --- a/plugins/net_api_plugin/net_api_plugin.cpp +++ b/plugins/net_api_plugin/net_api_plugin.cpp @@ -29,7 +29,7 @@ using namespace eosio; try { \ if (body.empty()) body = "{}"; \ INVOKE \ - cb(http_response_code, fc::json::to_string(result)); \ + cb(http_response_code, fc::variant(result)); \ } catch (...) { \ http_plugin::handle_exception(#api_name, #call_name, body, cb); \ } \ diff --git a/plugins/producer_api_plugin/producer_api_plugin.cpp b/plugins/producer_api_plugin/producer_api_plugin.cpp index 7fcde1ac98c..0ef7631c868 100644 --- a/plugins/producer_api_plugin/producer_api_plugin.cpp +++ b/plugins/producer_api_plugin/producer_api_plugin.cpp @@ -30,7 +30,7 @@ using namespace eosio; try { \ if (body.empty()) body = "{}"; \ INVOKE \ - cb(http_response_code, fc::json::to_string(result)); \ + cb(http_response_code, fc::variant(result)); \ } catch (...) { \ http_plugin::handle_exception(#api_name, #call_name, body, cb); \ } \ diff --git a/plugins/test_control_api_plugin/test_control_api_plugin.cpp b/plugins/test_control_api_plugin/test_control_api_plugin.cpp index 307cccc197e..a932a27cad9 100644 --- a/plugins/test_control_api_plugin/test_control_api_plugin.cpp +++ b/plugins/test_control_api_plugin/test_control_api_plugin.cpp @@ -40,8 +40,8 @@ struct async_result_visitor : public fc::visitor { [api_handle](string, string body, url_response_callback cb) mutable { \ try { \ if (body.empty()) body = "{}"; \ - auto result = api_handle.call_name(fc::json::from_string(body).as()); \ - cb(http_response_code, fc::json::to_string(result)); \ + fc::variant result( api_handle.call_name(fc::json::from_string(body).as()) ); \ + cb(http_response_code, std::move(result)); \ } catch (...) { \ http_plugin::handle_exception(#api_name, #call_name, body, cb); \ } \ diff --git a/plugins/txn_test_gen_plugin/txn_test_gen_plugin.cpp b/plugins/txn_test_gen_plugin/txn_test_gen_plugin.cpp index 460ecb57bd6..414664be32a 100755 --- a/plugins/txn_test_gen_plugin/txn_test_gen_plugin.cpp +++ b/plugins/txn_test_gen_plugin/txn_test_gen_plugin.cpp @@ -45,7 +45,7 @@ using io_work_t = boost::asio::executor_work_guard(argc, argv)) return -1; auto& http = app().get_plugin(); - http.add_handler("/v1/keosd/stop", [](string, string, url_response_callback cb) { cb(200, "{}"); std::raise(SIGTERM); } ); + http.add_handler("/v1/keosd/stop", [](string, string, url_response_callback cb) { cb(200, fc::variant(fc::variant_object())); std::raise(SIGTERM); } ); app().startup(); app().exec(); } catch (const fc::exception& e) {