From bda73a1de8ed7847a11032f70c5b32f629fb7768 Mon Sep 17 00:00:00 2001 From: WeijieSun Date: Fri, 18 May 2018 18:32:51 +0800 Subject: [PATCH] configuration: refactor configuration related APIs (#54) --- include/dsn/c/api_utilities.h | 41 ----- include/dsn/service_api_cpp.h | 2 - include/dsn/tool-api/task_spec.h | 2 +- include/dsn/tool-api/uri_address.h | 2 +- include/dsn/utility/config_api.h | 125 +++++++++++++++ include/dsn/{cpp => utility}/config_helper.h | 16 +- include/dsn/utility/configuration.h | 20 --- src/core/core/config_api.cpp | 72 +++++++++ src/core/core/configuration.cpp | 26 ++-- src/core/core/global_config.cpp | 33 ++-- src/core/core/perf_test_helper.cpp | 29 +--- src/core/core/rpc_engine.cpp | 5 +- src/core/core/rpc_engine.h | 6 +- src/core/core/service_api_c.cpp | 146 ++++-------------- src/core/core/service_engine.cpp | 4 +- src/core/core/service_engine.h | 1 - src/core/core/uri_address.cpp | 9 +- src/core/tests/clientlet.cpp | 3 +- src/core/tests/configuration.cpp | 7 +- src/core/tests/service_api_c.cpp | 12 +- .../replication/meta_server/server_state.cpp | 9 +- src/tools/repli/repli.app.cpp | 12 +- src/tools/repli/repli.main.cpp | 16 +- 23 files changed, 298 insertions(+), 300 deletions(-) create mode 100644 include/dsn/utility/config_api.h rename include/dsn/{cpp => utility}/config_helper.h (97%) create mode 100644 src/core/core/config_api.cpp diff --git a/include/dsn/c/api_utilities.h b/include/dsn/c/api_utilities.h index e5727eb654..f6c2b7d0f4 100644 --- a/include/dsn/c/api_utilities.h +++ b/include/dsn/c/api_utilities.h @@ -37,47 +37,6 @@ #include -/*! -@defgroup config Configuration Service -@ingroup service-api-utilities - - Configuration Service (e.g., config.ini) - -@{ -*/ - -extern DSN_API const char * -dsn_config_get_value_string(const char *section, ///< [section] - const char *key, ///< key = value - const char *default_value, ///< if [section] key is not present - const char *dsptr ///< what it is for, as help-info in config - ); -extern DSN_API bool dsn_config_get_value_bool(const char *section, - const char *key, - bool default_value, - const char *dsptr); -extern DSN_API uint64_t dsn_config_get_value_uint64(const char *section, - const char *key, - uint64_t default_value, - const char *dsptr); -extern DSN_API int64_t dsn_config_get_value_int64(const char *section, - const char *key, - int64_t default_value, - const char *dsptr); -extern DSN_API double dsn_config_get_value_double(const char *section, - const char *key, - double default_value, - const char *dsptr); -// return all section count (may greater than buffer_count) -extern DSN_API int dsn_config_get_all_sections(const char **buffers, - /*inout*/ int *buffer_count); -// return all key count (may greater than buffer_count) -extern DSN_API int dsn_config_get_all_keys(const char *section, - const char **buffers, - /*inout*/ int *buffer_count); -extern DSN_API void dsn_config_dump(const char *file); -/*@}*/ - /*! @defgroup logging Logging Service @ingroup service-api-utilities diff --git a/include/dsn/service_api_cpp.h b/include/dsn/service_api_cpp.h index 6753934349..d2406a4ad4 100644 --- a/include/dsn/service_api_cpp.h +++ b/include/dsn/service_api_cpp.h @@ -36,9 +36,7 @@ #pragma once #include -//# include #include -#include #include #include #include diff --git a/include/dsn/tool-api/task_spec.h b/include/dsn/tool-api/task_spec.h index d7a6a2f9aa..51240f7662 100644 --- a/include/dsn/tool-api/task_spec.h +++ b/include/dsn/tool-api/task_spec.h @@ -37,7 +37,7 @@ #include #include -#include +#include #include #include #include diff --git a/include/dsn/tool-api/uri_address.h b/include/dsn/tool-api/uri_address.h index 3ccf69bd8d..9dcb59f44c 100644 --- a/include/dsn/tool-api/uri_address.h +++ b/include/dsn/tool-api/uri_address.h @@ -36,7 +36,7 @@ #pragma once #include -#include +#include #include #include #include diff --git a/include/dsn/utility/config_api.h b/include/dsn/utility/config_api.h new file mode 100644 index 0000000000..d983f75423 --- /dev/null +++ b/include/dsn/utility/config_api.h @@ -0,0 +1,125 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 Microsoft Corporation + * + * -=- Robust Distributed System Nucleus (rDSN) -=- + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#pragma once + +#include +#include +#include + +/// load a ini configuration file, and replace specific strings in file with arguments. +/// +/// the rules of replacement is as follows: +/// 1. arguments are with format of k1=v1,k2=v2,k3=v3 +/// 2. if a string if file is %k1%, it will be replaced with v1. +/// %k2%, %k3% will be replaced to v2 and v3 in a similar fashion +/// +/// for example: +/// +/// the file content: +/// " +/// [example_section] +/// %replace_key% = real_value +/// real_port = %host_port% +/// " +/// +/// and the arguments "replace_key=key,host_port=8080 +/// +/// so the loaded config will be: +/// " +/// [example_section] +/// key = real_value +/// real_port = 8080 +/// +/// return true if load config file succeed, otherwise false +/// +/// please call this function at the beginning of your process, otherwise non of the +/// dsn_config_xxx function works +/// +/// the function is not thread safe. +bool dsn_config_load(const char *file, const char *arguments); + +/// dump the global configuration +void dsn_config_dump(std::ostream &os); + +/// the section format: +/// [section] +/// key = value +/// +/// this function get the value of a key in some section. +/// if is not present in section, then return default_value. +/// dsptr is the description of the key-value pairs. +/// +/// this function is not thread safe if get/set are concurrently called +const char *dsn_config_get_value_string(const char *section, + const char *key, + const char *default_value, + const char *dsptr); + +/// get value of a key in some section, the value should be "true" or "false" +/// this function is not thread safe if dsn_config_set is concurrently called +bool dsn_config_get_value_bool(const char *section, + const char *key, + bool default_value, + const char *dsptr); + +/// get value of a key in some section, the value should be decimal in range of uint64_t +/// this function is not thread safe if dsn_config_set is concurrently called +uint64_t dsn_config_get_value_uint64(const char *section, + const char *key, + uint64_t default_value, + const char *dsptr); + +/// get value of a key in some section, the value should be decimal in range of double +/// this function is not thread safe if dsn_config_set is concurrently called +double dsn_config_get_value_double(const char *section, + const char *key, + double default_value, + const char *dsptr); + +/// get the names of all sections +/// this function is not thread safe if dsn_config_set is concurrently called +void dsn_config_get_all_sections(/*out*/ std::vector §ions); + +/// get the names of all sections +/// this function is not thread safe if dsn_config_set is concurrently called +void dsn_config_get_all_sections(/*out*/ std::vector §ions); + +/// get all keys in some specific section +/// this function is not thread safe if dsn_config_set is concurrently called +void dsn_config_get_all_keys(const char *section, /*out*/ std::vector &keys); + +/// get all keys in some specific section +/// this function is not thread safe if dsn_config_set is concurrently called +void dsn_config_get_all_keys(const char *section, /*out*/ std::vector &keys); + +/// set value for a key of some section. +/// if the section doesn't exsit, a new one will be created. +/// if the key doesn't exist, a new one will be created +/// +/// multiple concurrent set are thread safe. +/// +/// any of dsn_config_get_xxx may corrupt if called concurrently with dsn_config_set +void dsn_config_set(const char *section, const char *key, const char *value, const char *dsptr); diff --git a/include/dsn/cpp/config_helper.h b/include/dsn/utility/config_helper.h similarity index 97% rename from include/dsn/cpp/config_helper.h rename to include/dsn/utility/config_helper.h index d51d55388b..458230b120 100644 --- a/include/dsn/cpp/config_helper.h +++ b/include/dsn/utility/config_helper.h @@ -24,20 +24,16 @@ * THE SOFTWARE. */ -/* - * Description: - * What is this file about? - * - * Revision history: - * xxxx-xx-xx, author, first version - * xxxx-xx-xx, author, fix bug about xxx - */ - #pragma once -#include +#include #include +/// you can use following macros to implement a function called "read_config" +/// to initialize a structure from the configuration file quickly +/// +/// please refer to "task_spec.h". it's a very good example + #define CONFIG_BEGIN(t_struct) \ inline bool read_config( \ const char *section, /*out*/ t_struct &val, t_struct *default_value = nullptr) \ diff --git a/include/dsn/utility/configuration.h b/include/dsn/utility/configuration.h index 04987040ef..4c3e20503c 100644 --- a/include/dsn/utility/configuration.h +++ b/include/dsn/utility/configuration.h @@ -23,17 +23,6 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ - -/* - * Description: - * configuration file interface - * - * Revision history: - * Mar., 2015, @imzhenyu (Zhenyu Guo), first version - * Jul., 2015, @imzhenyu (Zhenyu Guo), add parameter support - * xxxx-xx-xx, author, fix bug about xxx - */ - #pragma once #include @@ -48,12 +37,6 @@ namespace dsn { -class configuration; -typedef std::shared_ptr configuration_ptr; -typedef void (*config_file_change_notifier)(configuration_ptr); - -extern configuration_ptr get_main_config(); - class configuration { public: @@ -84,8 +67,6 @@ class configuration void set(const char *section, const char *key, const char *value, const char *dsptr); - void register_config_change_notification(config_file_change_notifier notifier); - bool has_section(const char *section); bool has_key(const char *section, const char *key); @@ -130,7 +111,6 @@ class configuration config_map _configs; std::string _file_name; - std::list _notifiers; std::string _file_data; bool _warning; }; diff --git a/src/core/core/config_api.cpp b/src/core/core/config_api.cpp new file mode 100644 index 0000000000..9235e2ffaf --- /dev/null +++ b/src/core/core/config_api.cpp @@ -0,0 +1,72 @@ +#include +#include +#include + +dsn::configuration g_config; + +bool dsn_config_load(const char *file, const char *arguments) +{ + return g_config.load(file, arguments); +} + +void dsn_config_dump(std::ostream &os) { g_config.dump(os); } + +const char *dsn_config_get_value_string(const char *section, + const char *key, + const char *default_value, + const char *dsptr) +{ + return g_config.get_string_value(section, key, default_value, dsptr); +} + +bool dsn_config_get_value_bool(const char *section, + const char *key, + bool default_value, + const char *dsptr) +{ + return g_config.get_value(section, key, default_value, dsptr); +} + +uint64_t dsn_config_get_value_uint64(const char *section, + const char *key, + uint64_t default_value, + const char *dsptr) +{ + return g_config.get_value(section, key, default_value, dsptr); +} + +double dsn_config_get_value_double(const char *section, + const char *key, + double default_value, + const char *dsptr) +{ + return g_config.get_value(section, key, default_value, dsptr); +} + +void dsn_config_get_all_sections(/*out*/ std::vector §ions) +{ + g_config.get_all_sections(sections); +} + +void dsn_config_get_all_sections(/*out*/ std::vector §ions) +{ + g_config.get_all_section_ptrs(sections); +} + +void dsn_config_get_all_keys(const char *section, std::vector &keys) +{ + std::vector key_ptrs; + g_config.get_all_keys(section, key_ptrs); + for (const char *p : key_ptrs) + keys.emplace_back(std::string(p)); +} + +void dsn_config_get_all_keys(const char *section, /*out*/ std::vector &keys) +{ + g_config.get_all_keys(section, keys); +} + +void dsn_config_set(const char *section, const char *key, const char *value, const char *dsptr) +{ + g_config.set(section, key, value, dsptr); +} diff --git a/src/core/core/configuration.cpp b/src/core/core/configuration.cpp index b77a182a82..09b96e8e76 100644 --- a/src/core/core/configuration.cpp +++ b/src/core/core/configuration.cpp @@ -33,20 +33,30 @@ * xxxx-xx-xx, author, fix bug about xxx */ -#include -#include -#include -#include #include #include #include #include +#include +#include +#include +#include + namespace dsn { configuration::configuration() { _warning = false; } -configuration::~configuration() {} +configuration::~configuration() +{ + for (auto §ion_kv : _configs) { + auto §ion = section_kv.second; + for (auto &kv : section) { + delete kv.second; + } + } + _configs.clear(); +} // arguments: k1=v1;k2=v2;k3=v3; ... // e.g., @@ -431,12 +441,6 @@ void configuration::set(const char *section, const char *key, const char *value, _lock.unlock(); } -void configuration::register_config_change_notification(config_file_change_notifier notifier) -{ - printf("ERROR: method register_config_change_notification() not implemented\n"); - ::abort(); -} - bool configuration::has_section(const char *section) { auto it = _configs.find(section); diff --git a/src/core/core/global_config.cpp b/src/core/core/global_config.cpp index d6cdf94b9e..e9d622ecfd 100644 --- a/src/core/core/global_config.cpp +++ b/src/core/core/global_config.cpp @@ -35,13 +35,14 @@ #include +#include +#include +#include + #include #include #include #include -#include -#include -#include namespace dsn { @@ -51,13 +52,11 @@ static bool build_client_network_confs(const char *section, { nss.clear(); - const char *keys[128]; - int kcapacity = 128; - int kcount = dsn_config_get_all_keys(section, keys, &kcapacity); - dassert(kcount <= 128, "kcount = %d", kcount); + std::vector keys; + dsn_config_get_all_keys(section, keys); - for (int i = 0; i < kcapacity; i++) { - std::string k = keys[i]; + for (const char *item : keys) { + std::string k(item); if (k.length() <= strlen("network.client.")) continue; @@ -125,13 +124,11 @@ static bool build_server_network_confs(const char *section, { nss.clear(); - const char *keys[128]; - int kcapacity = 128; - int kcount = dsn_config_get_all_keys(section, keys, &kcapacity); - dassert(kcount <= 128, "kcount = %d", kcount); + std::vector keys; + dsn_config_get_all_keys(section, keys); - for (int i = 0; i < kcapacity; i++) { - std::string k = keys[i]; + for (const char *item : keys) { + std::string k(item); if (k.length() <= strlen("network.server.")) continue; @@ -314,7 +311,7 @@ bool service_spec::init() bool service_spec::init_app_specs() { std::vector all_section_names; - get_main_config()->get_all_sections(all_section_names); + dsn_config_get_all_sections(all_section_names); // check mimic app const char *mimic_app_role_name = "dsn.app.mimic"; @@ -323,8 +320,8 @@ bool service_spec::init_app_specs() std::string mimic_section_name("apps.mimic"); if (std::find(all_section_names.begin(), all_section_names.end(), mimic_section_name) == all_section_names.end()) { - get_main_config()->set("apps.mimic", "type", mimic_app_role_name, ""); - get_main_config()->set("apps.mimic", "pools", "THREAD_POOL_DEFAULT", ""); + dsn_config_set("apps.mimic", "type", mimic_app_role_name, ""); + dsn_config_set("apps.mimic", "pools", "THREAD_POOL_DEFAULT", ""); all_section_names.push_back("apps.mimic"); } else { auto type = dsn_config_get_value_string("apps.mimic", "type", "", ""); diff --git a/src/core/core/perf_test_helper.cpp b/src/core/core/perf_test_helper.cpp index a9515642a9..9b6b4866bd 100644 --- a/src/core/core/perf_test_helper.cpp +++ b/src/core/core/perf_test_helper.cpp @@ -74,12 +74,10 @@ void perf_client_helper::start_test(const char *prefix, int max_request_kind_cou perf_test_suite s; std::vector suits; - const char *sections[10240]; - int scount, used_count = sizeof(sections) / sizeof(const char *); - scount = dsn_config_get_all_sections(sections, &used_count); - dassert(scount == used_count, "too many sections (>10240) defined in config files"); + std::vector sections; + dsn_config_get_all_sections(sections); - for (int i = 0; i < used_count; i++) { + for (int i = 0; i < sections.size(); i++) { if (strstr(sections[i], prefix) == sections[i]) { s.name = sections[i]; s.config_section = sections[i]; @@ -264,27 +262,6 @@ void perf_client_helper::start_next_case() } dwarn(ss.str().c_str()); - - // dump to perf result file - if (dsn_config_get_value_bool( - "apps.client.perf.test", - "exit_after_test", - false, - "dump the result and exit the process after the test is finished")) { - std::string data_dir(service_app::current_service_app_info().data_dir); - std::stringstream fns; - fns << "perf-result-" << ts << ".txt"; - std::string report = ::dsn::utils::filesystem::path_combine(data_dir, fns.str()); - std::ofstream result_f(report.c_str(), std::ios::out); - result_f << ss.str() << std::endl; - result_f.close(); - - report += ".config.ini"; - dsn_config_dump(report.c_str()); - - dsn_exit(0); - } - return; } } diff --git a/src/core/core/rpc_engine.cpp b/src/core/core/rpc_engine.cpp index 4b1e429848..cad235d1db 100644 --- a/src/core/core/rpc_engine.cpp +++ b/src/core/core/rpc_engine.cpp @@ -417,12 +417,9 @@ rpc_request_task *rpc_server_dispatcher::on_request(message_ex *msg, service_nod } //---------------------------------------------------------------------------------------------- -rpc_engine::rpc_engine(configuration_ptr config, service_node *node) - : _config(config), _node(node), _rpc_matcher(this) +rpc_engine::rpc_engine(service_node *node) : _node(node), _rpc_matcher(this) { dassert(_node != nullptr, ""); - dassert(_config != nullptr, ""); - _is_running = false; _is_serving = false; } diff --git a/src/core/core/rpc_engine.h b/src/core/core/rpc_engine.h index 2781d1d966..11cfc26d99 100644 --- a/src/core/core/rpc_engine.h +++ b/src/core/core/rpc_engine.h @@ -35,11 +35,10 @@ #pragma once +#include #include #include -#include #include -#include namespace dsn { @@ -141,7 +140,7 @@ class rpc_server_dispatcher class rpc_engine { public: - rpc_engine(configuration_ptr config, service_node *node); + explicit rpc_engine(service_node *node); // // management routines @@ -195,7 +194,6 @@ class rpc_engine io_modifer &ctx); private: - configuration_ptr _config; service_node *_node; std::vector> _client_nets; // > std::unordered_map> _server_nets; // > diff --git a/src/core/core/service_api_c.cpp b/src/core/core/service_api_c.cpp index 7f2b2a122a..9a67a99419 100644 --- a/src/core/core/service_api_c.cpp +++ b/src/core/core/service_api_c.cpp @@ -47,7 +47,7 @@ #include #include -#include +#include #include #include #include @@ -74,7 +74,6 @@ static struct _all_info_ bool engine_ready; bool config_completed; ::dsn::tools::tool_app *tool; - ::dsn::configuration_ptr config; ::dsn::service_engine *engine; std::vector<::dsn::task_spec *> task_specs; ::dsn::memory_provider *memory; @@ -96,88 +95,6 @@ DSN_API bool dsn_task_is_running_inside(dsn::task *t) return ::dsn::task::get_current_task() == t; } -DSN_API const char *dsn_config_get_value_string(const char *section, - const char *key, - const char *default_value, - const char *dsptr) -{ - return dsn_all.config->get_string_value(section, key, default_value, dsptr); -} - -DSN_API bool dsn_config_get_value_bool(const char *section, - const char *key, - bool default_value, - const char *dsptr) -{ - return dsn_all.config->get_value(section, key, default_value, dsptr); -} - -DSN_API uint64_t dsn_config_get_value_uint64(const char *section, - const char *key, - uint64_t default_value, - const char *dsptr) -{ - return dsn_all.config->get_value(section, key, default_value, dsptr); -} - -DSN_API int64_t dsn_config_get_value_int64(const char *section, - const char *key, - int64_t default_value, - const char *dsptr) -{ - return dsn_all.config->get_value(section, key, default_value, dsptr); -} - -DSN_API double dsn_config_get_value_double(const char *section, - const char *key, - double default_value, - const char *dsptr) -{ - return dsn_all.config->get_value(section, key, default_value, dsptr); -} - -DSN_API int dsn_config_get_all_sections(const char **buffers, /*inout*/ int *buffer_count) -{ - std::vector sections; - dsn_all.config->get_all_section_ptrs(sections); - int scount = (int)sections.size(); - - if (*buffer_count > scount) - *buffer_count = scount; - - for (int i = 0; i < *buffer_count; i++) { - buffers[i] = sections[i]; - } - - return scount; -} - -DSN_API int dsn_config_get_all_keys( - const char *section, - const char **buffers, - /*inout*/ int *buffer_count) // return all key count (may greater than buffer_count) -{ - std::vector keys; - dsn_all.config->get_all_keys(section, keys); - int kcount = (int)keys.size(); - - if (*buffer_count > kcount) - *buffer_count = kcount; - - for (int i = 0; i < *buffer_count; i++) { - buffers[i] = keys[i]; - } - - return kcount; -} - -DSN_API void dsn_config_dump(const char *file) -{ - std::ofstream os(file, std::ios::out); - dsn_all.config->dump(os); - os.close(); -} - DSN_API void dsn_coredump() { ::dsn::utils::coredump::write(); @@ -772,20 +689,19 @@ bool run(const char *config_file, dsn_all.config_completed = false; dsn_all.tool = nullptr; dsn_all.engine = &::dsn::service_engine::instance(); - dsn_all.config.reset(new ::dsn::configuration()); dsn_all.memory = nullptr; dsn_all.magic = 0xdeadbeef; - if (!dsn_all.config->load(config_file, config_arguments)) { + if (!dsn_config_load(config_file, config_arguments)) { printf("Fail to load config file %s\n", config_file); return false; } // pause when necessary - if (dsn_all.config->get_value("core", - "pause_on_start", - false, - "whether to pause at startup time for easier debugging")) { + if (dsn_config_get_value_bool("core", + "pause_on_start", + false, + "whether to pause at startup time for easier debugging")) { #if defined(_WIN32) printf("\nPause for debugging (pid = %d)...\n", static_cast(::GetCurrentProcessId())); #else @@ -844,7 +760,7 @@ bool run(const char *config_file, } // init tool memory - auto tls_trans_memory_KB = (size_t)dsn_all.config->get_value( + size_t tls_trans_memory_KB = (size_t)dsn_config_get_value_uint64( "core", "tls_trans_memory_KB", 1024, // 1 MB @@ -895,8 +811,8 @@ bool run(const char *config_file, bool create_it = false; - if (app_list == "") // create all apps - { + // create all apps + if (app_list == "") { create_it = true; } else { for (auto &kv : applistkvs) { @@ -924,7 +840,7 @@ bool run(const char *config_file, exit(1); } - if (dsn_all.config->get_value( + if (dsn_config_get_value_bool( "core", "cli_remote", true, @@ -932,25 +848,24 @@ bool run(const char *config_file, ::dsn::command_manager::instance().start_remote_cli(); } - // register local cli commands - ::dsn::command_manager::instance().register_command({"config-dump"}, - "config-dump - dump configuration", - "config-dump [to-this-config-file]", - [](const std::vector &args) { - std::ostringstream oss; - std::ofstream off; - std::ostream *os = &oss; - if (args.size() > 0) { - off.open(args[0]); - os = &off; - - oss << "config dump to file " - << args[0] << std::endl; - } - - dsn_all.config->dump(*os); - return oss.str(); - }); + dsn::command_manager::instance().register_command({"config-dump"}, + "config-dump - dump configuration", + "config-dump [to-this-config-file]", + [](const std::vector &args) { + std::ostringstream oss; + std::ofstream off; + std::ostream *os = &oss; + if (args.size() > 0) { + off.open(args[0]); + os = &off; + + oss << "config dump to file " + << args[0] << std::endl; + } + + dsn_config_dump(*os); + return oss.str(); + }); // invoke customized init after apps are created dsn::tools::sys_init_after_app_created.execute(); @@ -958,7 +873,6 @@ bool run(const char *config_file, // start the tool dsn_all.tool->run(); - // if (sleep_after_init) { while (true) { std::this_thread::sleep_for(std::chrono::hours(1)); @@ -971,10 +885,6 @@ bool run(const char *config_file, return true; } -namespace dsn { -configuration_ptr get_main_config() { return dsn_all.config; } -} - namespace dsn { service_app *service_app::new_service_app(const std::string &type, const dsn::service_app_info *info) diff --git a/src/core/core/service_engine.cpp b/src/core/core/service_engine.cpp index c17dd9892b..82efb6783a 100644 --- a/src/core/core/service_engine.cpp +++ b/src/core/core/service_engine.cpp @@ -129,7 +129,7 @@ error_code service_node::init_io_engine(io_engine &io, ioe_mode mode) ctx.port_shift_value = spec.get_ports_delta(_app_spec.id, io.pool->spec().pool_code, io.q->index()); } - io.rpc = new rpc_engine(get_main_config(), this); + io.rpc = new rpc_engine(this); } else io.rpc = nullptr; @@ -548,6 +548,4 @@ std::string service_engine::get_queue_info(const std::vector &args) return ss.str(); } -void service_engine::configuration_changed() { task_spec::init(); } - } // end namespace diff --git a/src/core/core/service_engine.h b/src/core/core/service_engine.h index ee7d6d0460..e523deb4bd 100644 --- a/src/core/core/service_engine.h +++ b/src/core/core/service_engine.h @@ -152,7 +152,6 @@ class service_engine : public utils::singleton void init_before_toollets(const service_spec &spec); void init_after_toollets(); - void configuration_changed(); service_node *start_node(service_app_spec &app_spec); diff --git a/src/core/core/uri_address.cpp b/src/core/core/uri_address.cpp index f0b6885727..fd48dba45f 100644 --- a/src/core/core/uri_address.cpp +++ b/src/core/core/uri_address.cpp @@ -33,16 +33,17 @@ * xxxx-xx-xx, author, fix bug about xxx */ -#include "rpc_engine.h" -#include #include +#include #include -#include #include +#include #include #include #include +#include "rpc_engine.h" + namespace dsn { void uri_resolver_manager::setup_resolvers() { @@ -51,7 +52,7 @@ void uri_resolver_manager::setup_resolvers() // arguments = %uri-resolver-arguments% std::vector sections; - get_main_config()->get_all_sections(sections); + dsn_config_get_all_sections(sections); const int prefix_len = (const int)strlen("uri-resolver."); for (auto &s : sections) { diff --git a/src/core/tests/clientlet.cpp b/src/core/tests/clientlet.cpp index 02ff23fab5..5a22bd8e17 100644 --- a/src/core/tests/clientlet.cpp +++ b/src/core/tests/clientlet.cpp @@ -189,8 +189,7 @@ DEFINE_TASK_CODE_RPC(TEST_CODE, TASK_PRIORITY_COMMON, THREAD_POOL_TEST_SERVER) TEST(dev_cpp, task_destructor) { { - task_ptr t(new simple_task(LPC_TEST_CLIENTLET, - [=]() { ddebug("the pointer in t is (%p)", t.get()); })); + task_ptr t(new simple_task(LPC_TEST_CLIENTLET, nullptr)); t->enqueue(); t->wait(); ASSERT_EQ(1, simple_task::allocate_count); diff --git a/src/core/tests/configuration.cpp b/src/core/tests/configuration.cpp index 41aa964db8..da44d409c7 100644 --- a/src/core/tests/configuration.cpp +++ b/src/core/tests/configuration.cpp @@ -33,16 +33,17 @@ * xxxx-xx-xx, author, fix bug about xxx */ -#include -#include #include #include +#include + +#include using namespace ::dsn; TEST(core, configuration) { - configuration_ptr c; + std::shared_ptr c; printf("load not_exist_config_file\n"); c.reset(new configuration()); diff --git a/src/core/tests/service_api_c.cpp b/src/core/tests/service_api_c.cpp index d60841b5ca..85766a6e9f 100644 --- a/src/core/tests/service_api_c.cpp +++ b/src/core/tests/service_api_c.cpp @@ -136,16 +136,12 @@ TEST(core, dsn_config) ASSERT_EQ(1u, dsn_config_get_value_uint64("apps.client", "count", 100, "client count")); ASSERT_EQ(1.0, dsn_config_get_value_double("apps.client", "count", 100.0, "client count")); ASSERT_EQ(1.0, dsn_config_get_value_double("apps.client", "count", 100.0, "client count")); - const char *buffers[100]; - int buffer_count = 100; - ASSERT_EQ(2, dsn_config_get_all_keys("core.test", buffers, &buffer_count)); - ASSERT_EQ(2, buffer_count); + + std::vector buffers; + dsn_config_get_all_keys("core.test", buffers); + ASSERT_EQ(2, buffers.size()); ASSERT_STREQ("count", buffers[0]); ASSERT_STREQ("run", buffers[1]); - buffer_count = 1; - ASSERT_EQ(2, dsn_config_get_all_keys("core.test", buffers, &buffer_count)); - ASSERT_EQ(1, buffer_count); - ASSERT_STREQ("count", buffers[0]); } TEST(core, dsn_coredump) {} diff --git a/src/dist/replication/meta_server/server_state.cpp b/src/dist/replication/meta_server/server_state.cpp index 5900f3de86..8fb05c93bf 100644 --- a/src/dist/replication/meta_server/server_state.cpp +++ b/src/dist/replication/meta_server/server_state.cpp @@ -417,15 +417,12 @@ error_code server_state::restore_from_local_storage(const char *local_path) error_code server_state::initialize_default_apps() { - const char *sections[10240]; - int total_sections; - int used_sections = sizeof(sections) / sizeof(const char *); - total_sections = dsn_config_get_all_sections(sections, &used_sections); - dassert(total_sections == used_sections, "too many sections (>10240) defined in config files"); + std::vector sections; + dsn_config_get_all_sections(sections); ddebug("start to do initialize"); app_info default_app; - for (int i = 0; i < used_sections; i++) { + for (int i = 0; i < sections.size(); i++) { if (strstr(sections[i], "meta_server.apps") == sections[i] || strcmp(sections[i], "replication.app") == 0) { const char *s = sections[i]; diff --git a/src/tools/repli/repli.app.cpp b/src/tools/repli/repli.app.cpp index 1a8917ebc9..24f4cac6d8 100644 --- a/src/tools/repli/repli.app.cpp +++ b/src/tools/repli/repli.app.cpp @@ -36,13 +36,11 @@ #include #include #include +#include #include "dist/replication/lib/mutation_log.h" - #include "repli.app.h" -#include - namespace dsn { namespace service { @@ -132,14 +130,14 @@ error_code repli_app::start(const std::vector &args) return ERR_OK; } - ::dsn::configuration_ptr config(new ::dsn::configuration()); - if (!config->load(s_args[1].c_str(), nullptr)) { + ::dsn::configuration config; + if (!config.load(s_args[1].c_str(), nullptr)) { std::cerr << "ERROR: failed to load config file \"" << s_args[1] << "\"" << std::endl; g_done = true; return ERR_OK; } - config->set_warning(true); - const char *result = config->get_string_value(s_args[2].c_str(), s_args[3].c_str(), "", ""); + config.set_warning(true); + const char *result = config.get_string_value(s_args[2].c_str(), s_args[3].c_str(), "", ""); std::cout << result << std::endl; } else { std::cerr << "ERROR: invalid command: " << cmd << std::endl; diff --git a/src/tools/repli/repli.main.cpp b/src/tools/repli/repli.main.cpp index 6cb67d25ba..3f43b19364 100644 --- a/src/tools/repli/repli.main.cpp +++ b/src/tools/repli/repli.main.cpp @@ -33,14 +33,14 @@ * xxxx-xx-xx, author, fix bug about xxx */ -#include "repli.app.h" -#include -#include #include #include -#if !defined(_WIN32) -#include "unistd.h" -#endif +#include + +#include +#include + +#include "repli.app.h" bool g_done = false; @@ -56,11 +56,7 @@ int main(int argc, char **argv) char buf[4096]; int slen; -#if defined(_WIN32) - slen = ::GetModuleFileNameA(NULL, buf, sizeof(buf)); -#else slen = readlink("/proc/self/exe", buf, sizeof(buf)); -#endif if (slen != -1) { dassert(slen < 4906, "invalid slen, slen = %d", slen);