void server_state::init_app() { zauto_write_lock l(_lock); if (_apps.size() > 0) return; app_state app; app.app_id = 1; app.app_name = dsn_config_get_value_string("replication.app", "app_name", "", "replication app name"); dassert(app.app_name.length() > 0, "'[replication.app] app_name' not specified"); app.app_type = dsn_config_get_value_string("replication.app", "app_type", "", "replication app type-name"); dassert(app.app_type.length() > 0, "'[replication.app] app_type' not specified"); app.partition_count = (int)dsn_config_get_value_uint64("replication.app", "partition_count", 1, "how many partitions the app should have"); int32_t max_replica_count = (int)dsn_config_get_value_uint64("replication.app", "max_replica_count", 3, "maximum replica count for each partition"); for (int i = 0; i < app.partition_count; i++) { partition_configuration ps; ps.app_type = app.app_type; ps.ballot = 0; ps.gpid.app_id = app.app_id; ps.gpid.pidx = i; ps.last_committed_decree = 0; ps.max_replica_count = max_replica_count; ps.primary.set_invalid(); app.partitions.push_back(ps); } _apps.push_back(app); }
uint32_t network::get_local_ipv4() { static const char* explicit_host = dsn_config_get_value_string( "network", "explicit_host_address", "", "explicit host name or ip (v4) assigned to this node (e.g., service ip for pods in kubernets)" ); static const char* inteface = dsn_config_get_value_string( "network", "primary_interface", "", "network interface name used to init primary ipv4 address, if empty, means using the first \"eth\" prefixed non-loopback ipv4 address"); uint32_t ip = 0; if (strlen(explicit_host) > 0) { ip = dsn_ipv4_from_host(explicit_host); } if (0 == ip) { ip = dsn_ipv4_local(inteface); } if (0 == ip) { char name[128]; if (gethostname(name, sizeof(name)) != 0) { dassert(false, "gethostname failed, err = %s\n", strerror(errno)); } ip = dsn_ipv4_from_host(name); } return ip; }
meta_server_failure_detector::meta_server_failure_detector(server_state* state, meta_service* svc) { _is_primary = false; _state = state; _svc = svc; const char* distributed_lock_service_type = dsn_config_get_value_string( "meta_server", "distributed_lock_service_type", "distributed_lock_service_simple", "distributed_lock_service provider type" ); const char* distributed_lock_service_parameters = dsn_config_get_value_string( "meta_server", "distributed_lock_service_parameters", "", "distributed_lock_service provider parameters" ); // prepare parameters std::vector<std::string> args; dsn::utils::split_args(distributed_lock_service_parameters, args); int argc = static_cast<int>(args.size()); std::vector<const char*> args_ptr; args_ptr.resize(argc); for (int i = argc - 1; i >= 0; i--) { args_ptr[i] = args[i].c_str(); } // create lock service _lock_svc = dsn::utils::factory_store< ::dsn::dist::distributed_lock_service>::create( distributed_lock_service_type, PROVIDER_TYPE_MAIN ); error_code err = _lock_svc->initialize(argc, argc > 0 ? &args_ptr[0] : nullptr); dassert(err == ERR_OK, "init distributed_lock_service failed, err = %s", err.to_string()); _primary_lock_id = "dsn.meta.server.leader"; ddebug("init meta_server_failure_detector succeed"); }
machine_pool_mgr::machine_pool_mgr(const char* path) { ::dsn::service::zauto_lock l(_lock); std::string cluster_config_file = dsn_config_get_value_string(path, "node_list_path", "nodes", "the location of the file which lists the host name and user name of all the available machines"); std::vector<std::string> machine_id; error_code err = parse_cluster_config_file(cluster_config_file, machine_id); dassert(ERR_OK == err, "unable to load the cluster config file, pls check your config file again."); for (auto& i : machine_id) { machine_info machine; machine.workload.instance = 0; machine.identity = i; _machines[i] = machine; } }
void uri_resolver_manager::setup_resolvers() { // [uri-resolver.%resolver-address%] // factory = %uri-resolver-factory% // arguments = %uri-resolver-arguments% std::vector<std::string> sections; get_main_config()->get_all_sections(sections); const int prefix_len = (const int)strlen("uri-resolver."); for (auto& s : sections) { if (s.substr(0, prefix_len) != std::string("uri-resolver.")) continue; auto resolver_addr = s.substr(prefix_len); auto it = _resolvers.find(resolver_addr); if (it != _resolvers.end()) { dwarn("duplicated uri-resolver definition in config file, for '%s'", resolver_addr.c_str() ); continue; } auto factory = dsn_config_get_value_string(s.c_str(), "factory", "", "partition-resolver factory name which creates the concrete partition-resolver object"); auto arguments = dsn_config_get_value_string(s.c_str(), "arguments", "", "uri-resolver ctor arguments"); auto resolver = new uri_resolver(resolver_addr.c_str(), factory, arguments); _resolvers.emplace(resolver_addr, std::shared_ptr<uri_resolver>(resolver)); dinfo("initialize uri-resolver %s", resolver_addr.c_str()); } }
error_code docker_scheduler::initialize() { _run_path = dsn_config_get_value_string("apps.client","run_path","",""); dassert( _run_path != "", "run path is empty"); dinfo("run path is %s",_run_path.c_str()); #ifndef _WIN32 int ret; FILE *in; ret = system("docker version"); if (ret != 0) { dinfo("docker is not in the PATH"); return ::dsn::dist::ERR_DOCKER_BINARY_NOT_FOUND; } in = popen("service docker status","r"); if (in == nullptr) { dinfo("docker daemon is not running"); return ::dsn::dist::ERR_DOCKER_DAEMON_NOT_FOUND; } else { char buff[512]; while( fgets(buff,sizeof(buff),in) != nullptr) { constexpr const char substr[] = "docker start/running"; constexpr size_t length = sizeof(substr) - 1; if( strncmp(substr,buff,length) != 0 ) { dinfo("docker daemon is not running"); return ::dsn::dist::ERR_DOCKER_DAEMON_NOT_FOUND; } } } pclose(in); #endif dassert(_docker_deploy_handle == nullptr, "docker deploy is initialized twice"); _docker_deploy_handle = dsn_cli_app_register("deploy","deploy onto docker scheduler","",this,&deploy_docker_unit,&deploy_docker_unit_cleanup); dassert(_docker_deploy_handle != nullptr, "register cli handler failed"); dassert(_docker_undeploy_handle == nullptr, "docker undeploy is initialized twice"); _docker_undeploy_handle = dsn_cli_app_register("undeploy","undeploy from docker scheduler","",this,&undeploy_docker_unit,&undeploy_docker_unit_cleanup); dassert(_docker_undeploy_handle != nullptr, "register cli handler failed"); return ::dsn::ERR_OK; }
void replica_helper::load_meta_servers(/*out*/ std::vector<dsn::rpc_address>& servers, const char* section, const char* key) { servers.clear(); std::string server_list = dsn_config_get_value_string(section, key, "", ""); std::vector<std::string> lv; ::dsn::utils::split_args(server_list.c_str(), lv, ','); for (auto& s : lv) { // name:port auto pos1 = s.find_first_of(':'); if (pos1 != std::string::npos) { ::dsn::rpc_address ep(s.substr(0, pos1).c_str(), atoi(s.substr(pos1 + 1).c_str())); servers.push_back(ep); } } dassert(servers.size() > 0, "no meta server specified in config [%s].%s", section, key); }
network::network(rpc_engine* srv, network* inner_provider) : _engine(srv), _client_hdr_format(NET_HDR_DSN), _unknown_msg_header_format(NET_HDR_INVALID) { _message_buffer_block_size = 1024 * 64; _max_buffer_block_count_per_send = 64; // TODO: windows, how about the other platforms? _send_queue_threshold = (int)dsn_config_get_value_uint64( "network", "send_queue_threshold", 4 * 1024, "send queue size above which throttling is applied" ); _unknown_msg_header_format = network_header_format::from_string( dsn_config_get_value_string( "network", "unknown_message_header_format", NET_HDR_INVALID.to_string(), "format for unknown message headers, default is NET_HDR_INVALID" ), NET_HDR_INVALID); }
void replication_options::initialize() { dsn_app_info app_info; bool r = dsn_get_current_app_info(&app_info); dassert(r, "get current app info failed"); app_name = app_info.name; app_dir = app_info.data_dir; // slog_dir: // - if config[slog_dir] is empty: "app_dir/slog" // - else: "config[slog_dir]/app_name/slog" slog_dir = dsn_config_get_value_string("replication", "slog_dir", "", "shared log directory"); if (slog_dir.empty()) { slog_dir = app_dir; } else { slog_dir = utils::filesystem::path_combine(slog_dir, app_name); } slog_dir = utils::filesystem::path_combine(slog_dir, "slog"); // data_dirs // - if config[data_dirs] is empty: "app_dir/reps" // - else: "config[data_dirs]/app_name/reps" std::string dirs_str = dsn_config_get_value_string("replication", "data_dirs", "", "replica directory list"); std::vector<std::string> dirs; ::dsn::utils::split_args(dirs_str.c_str(), dirs, ','); if (dirs.empty()) { dirs.push_back(app_dir); } else { for (auto& dir : dirs) { dir = utils::filesystem::path_combine(dir, app_name); } } for (auto& dir : dirs) { data_dirs.push_back(utils::filesystem::path_combine(dir, "reps")); } prepare_timeout_ms_for_secondaries = (int)dsn_config_get_value_uint64("replication", "prepare_timeout_ms_for_secondaries", prepare_timeout_ms_for_secondaries, "timeout (ms) for prepare message to secondaries in two phase commit" ); prepare_timeout_ms_for_potential_secondaries = (int)dsn_config_get_value_uint64("replication", "prepare_timeout_ms_for_potential_secondaries", prepare_timeout_ms_for_potential_secondaries, "timeout (ms) for prepare message to potential secondaries in two phase commit" ); batch_write_disabled = dsn_config_get_value_bool("replication", "batch_write_disabled", batch_write_disabled, "whether to disable auto-batch of replicated write requests" ); staleness_for_commit = (int)dsn_config_get_value_uint64("replication", "staleness_for_commit", staleness_for_commit, "how many concurrent two phase commit rounds are allowed" ); max_mutation_count_in_prepare_list = (int)dsn_config_get_value_uint64("replication", "max_mutation_count_in_prepare_list", max_mutation_count_in_prepare_list, "maximum number of mutations in prepare list" ); mutation_2pc_min_replica_count = (int)dsn_config_get_value_uint64("replication", "mutation_2pc_min_replica_count", mutation_2pc_min_replica_count, "minimum number of alive replicas under which write is allowed" ); group_check_disabled = dsn_config_get_value_bool("replication", "group_check_disabled", group_check_disabled, "whether group check is disabled" ); group_check_interval_ms = (int)dsn_config_get_value_uint64("replication", "group_check_interval_ms", group_check_interval_ms, "every what period (ms) we check the replica healthness" ); checkpoint_disabled = dsn_config_get_value_bool("replication", "checkpoint_disabled", checkpoint_disabled, "whether checkpoint is disabled" ); checkpoint_interval_seconds = (int)dsn_config_get_value_uint64("replication", "checkpoint_interval_seconds", checkpoint_interval_seconds, "every what period (seconds) we do checkpoints for replicated apps" ); checkpoint_min_decree_gap = (int64_t)dsn_config_get_value_uint64("replication", "checkpoint_min_decree_gap", checkpoint_min_decree_gap, "minimum decree gap that triggers checkpoint" ); checkpoint_max_interval_hours = (int)dsn_config_get_value_uint64("replication", "checkpoint_max_interval_hours", checkpoint_max_interval_hours, "maximum time interval (hours) where a new checkpoint must be created" ); gc_disabled = dsn_config_get_value_bool("replication", "gc_disabled", gc_disabled, "whether to disable garbage collection" ); gc_interval_ms = (int)dsn_config_get_value_uint64("replication", "gc_interval_ms", gc_interval_ms, "every what period (ms) we do garbage collection for dead replicas, on-disk state, log, etc." ); gc_memory_replica_interval_ms = (int)dsn_config_get_value_uint64("replication", "gc_memory_replica_interval_ms", gc_memory_replica_interval_ms, "after closing a healthy replica (due to LB), the replica will remain in memory for this long (ms) for quick recover" ); gc_disk_error_replica_interval_seconds = (int)dsn_config_get_value_uint64("replication", "gc_disk_error_replica_interval_seconds", gc_disk_error_replica_interval_seconds, "error replica are deleted after they have been closed and lasted on disk this long (seconds)" ); fd_disabled = dsn_config_get_value_bool("replication", "fd_disabled", fd_disabled, "whether to disable failure detection" ); fd_check_interval_seconds = (int)dsn_config_get_value_uint64("replication", "fd_check_interval_seconds", fd_check_interval_seconds, "every this period(seconds) the FD will check healthness of remote peers" ); fd_beacon_interval_seconds = (int)dsn_config_get_value_uint64("replication", "fd_beacon_interval_seconds", fd_beacon_interval_seconds, "every this period(seconds) the FD sends beacon message to remote peers" ); fd_lease_seconds = (int)dsn_config_get_value_uint64("replication", "fd_lease_seconds", fd_lease_seconds, "lease (seconds) get from remote FD master" ); fd_grace_seconds = (int)dsn_config_get_value_uint64("replication", "fd_grace_seconds", fd_grace_seconds, "grace (seconds) assigned to remote FD slaves (grace > lease)" ); log_private_disabled = dsn_config_get_value_bool("replication", "log_private_disabled", log_private_disabled, "whether to disable logging committed mutations for each app, which is used for easier learning" ); log_private_file_size_mb = (int)dsn_config_get_value_uint64("replication", "log_private_file_size_mb", log_private_file_size_mb, "private log maximum segment file size (MB)" ); log_private_batch_buffer_kb = (int)dsn_config_get_value_uint64("replication", "log_private_batch_buffer_kb", log_private_batch_buffer_kb, "private log buffer size (KB) for batching incoming logs" ); log_private_force_flush = dsn_config_get_value_bool("replication", "log_private_force_flush", log_private_force_flush, "when write private log, whether to flush file after write done" ); log_shared_file_size_mb = (int)dsn_config_get_value_uint64("replication", "log_shared_file_size_mb", log_shared_file_size_mb, "shared log maximum segment file size (MB)" ); log_shared_batch_buffer_kb = (int)dsn_config_get_value_uint64("replication", "log_batch_buffer_KB_shared", log_shared_batch_buffer_kb, "shared log buffer size (KB) for batching incoming logs" ); log_shared_force_flush = dsn_config_get_value_bool("replication", "log_shared_force_flush", log_shared_force_flush, "when write shared log, whether to flush file after write done" ); config_sync_disabled = dsn_config_get_value_bool("replication", "config_sync_disabled", config_sync_disabled, "whether to disable replica configuration periodical sync with the meta server" ); config_sync_interval_ms = (int)dsn_config_get_value_uint64("replication", "config_sync_interval_ms", config_sync_interval_ms, "every this period(ms) the replica syncs replica configuration with the meta server" ); lb_interval_ms = (int)dsn_config_get_value_uint64("replication", "lb_interval_ms", lb_interval_ms, "every this period(ms) the meta server will do load balance" ); write_empty_enabled = dsn_config_get_value_bool("replication", "write_empty_enabled", write_empty_enabled, "whether to enable empty write when no write requests are processed for more than group_check_period, default is true" ); read_meta_servers(); sanity_check(); }
simple_logger::simple_logger(const char* log_dir, logging_provider* inner) : logging_provider(log_dir, inner) { _log_dir = std::string(log_dir); //we assume all valid entries are positive _start_index = 0; _index = 1; _lines = 0; _log = nullptr; _short_header = dsn_config_get_value_bool("tools.simple_logger", "short_header", true, "whether to use short header (excluding file/function etc.)"); _fast_flush = dsn_config_get_value_bool("tools.simple_logger", "fast_flush", false, "whether to flush immediately"); _stderr_start_level = enum_from_string( dsn_config_get_value_string("tools.simple_logger", "stderr_start_level", enum_to_string(LOG_LEVEL_WARNING), "copy log messages at or above this level to stderr in addition to logfiles"), LOG_LEVEL_INVALID ); dassert(_stderr_start_level != LOG_LEVEL_INVALID, "invalid [tools.simple_logger] stderr_start_level specified"); _max_number_of_log_files_on_disk = dsn_config_get_value_uint64( "tools.simple_logger", "max_number_of_log_files_on_disk", 20, "max number of log files reserved on disk, older logs are auto deleted" ); // check existing log files std::vector<std::string> sub_list; if (!dsn::utils::filesystem::get_subfiles(_log_dir, sub_list, false)) { dassert(false, "Fail to get subfiles in %s.", _log_dir.c_str()); } for (auto& fpath : sub_list) { auto&& name = dsn::utils::filesystem::get_file_name(fpath); if (name.length() <= 8 || name.substr(0, 4) != "log.") continue; int index; if (1 != sscanf(name.c_str(), "log.%d.txt", &index) || index <= 0) continue; if (index > _index) _index = index; if (_start_index == 0 || index < _start_index) _start_index = index; } sub_list.clear(); if (_start_index == 0) { _start_index = _index; } else ++_index; create_log_file(); }
error_code deploy_svc_service_impl::start() { std::string pdir = utils::filesystem::path_combine(dsn_get_current_app_data_dir(), "services"); _service_dir = dsn_config_get_value_string("deploy.service", "deploy_dir", pdir.c_str(), "where to put temporal deployment resources" ); // load clusters const char* clusters[100]; int sz = 100; int count = dsn_config_get_all_keys("deploy.service.clusters", clusters, &sz); dassert(count <= 100, "too many clusters"); for (int i = 0; i < count; i++) { std::string cluster_name = dsn_config_get_value_string( clusters[i], "name", "", "cluster name" ); if (nullptr != get_cluster(cluster_name)) { derror("cluster %s already defined", cluster_name.c_str()); return ERR_CLUSTER_ALREADY_EXIST; } std::string cluster_factory_type = dsn_config_get_value_string( clusters[i], "factory", "", "factory name to create the target cluster scheduler" ); auto cluster = ::dsn::utils::factory_store<cluster_scheduler>::create( cluster_factory_type.c_str(), PROVIDER_TYPE_MAIN ); if (nullptr == cluster) { derror("cluster type %s is not defined", cluster_factory_type.c_str()); return ERR_OBJECT_NOT_FOUND; } std::shared_ptr<cluster_ex> ce(new cluster_ex); ce->scheduler.reset(cluster); ce->cluster.name = cluster_name; ce->cluster.type = cluster->type(); _clusters[cluster_name] = ce; } _cli_deploy = dsn_cli_app_register( "deploy", "deploy deploy_request(in json format)", "deploy an app via our deployment service", (void*)this, [](void *context, int argc, const char **argv, dsn_cli_reply *reply) { auto this_ = (deploy_svc_service_impl*)context; this_->on_deploy_cli(context, argc, argv, reply); }, __svc_cli_freeer__ ); _cli_undeploy = dsn_cli_app_register( "undeploy", "undeploy service_name(in json format)", "undeploy an app via our deployment service", (void*)this, [](void *context, int argc, const char **argv, dsn_cli_reply *reply) { auto this_ = (deploy_svc_service_impl*)context; this_->on_undeploy_cli(context, argc, argv, reply); }, __svc_cli_freeer__ ); _cli_get_service_list = dsn_cli_app_register( "service_list", "service_list package_id(in json format)", "get service list of a package via our deployment service", (void*)this, [](void *context, int argc, const char **argv, dsn_cli_reply *reply) { auto this_ = (deploy_svc_service_impl*)context; this_->on_get_service_list_cli(context, argc, argv, reply); }, __svc_cli_freeer__ ); _cli_get_service_info = dsn_cli_app_register( "service_info", "service_info service_name(in json format)", "get service info of a service via our deployment service", (void*)this, [](void *context, int argc, const char **argv, dsn_cli_reply *reply) { auto this_ = (deploy_svc_service_impl*)context; this_->on_get_service_info_cli(context, argc, argv, reply); }, __svc_cli_freeer__ ); _cli_get_cluster_list = dsn_cli_app_register( "cluster_list", "cluster_list format(in json format)", "get cluster list with a specific format via our deployment service", (void*)this, [](void *context, int argc, const char **argv, dsn_cli_reply *reply) { auto this_ = (deploy_svc_service_impl*)context; this_->on_get_cluster_list_cli(context, argc, argv, reply); }, __svc_cli_freeer__ ); return ERR_OK; }
error_code meta_service::start() { dassert(!_started, "meta service is already started"); // init server state error_code err = _state->initialize(); if (err != ERR_OK) { derror("init server_state failed, err = %s", err.to_string()); return err; } ddebug("init server state succeed"); // we should start the FD service to response to the workers fd request _failure_detector = new meta_server_failure_detector(_state, this); err = _failure_detector->start( _opts.fd_check_interval_seconds, _opts.fd_beacon_interval_seconds, _opts.fd_lease_seconds, _opts.fd_grace_seconds, false ); if (err != ERR_OK) { derror("start failure_detector failed, err = %s", err.to_string()); return err; } // should register rpc handlers before acquiring leader lock, so that this meta service // can tell others who is the current leader register_rpc_handlers(); // become leader _failure_detector->acquire_leader_lock(); dassert(_failure_detector->is_primary(), "must be primary at this point"); ddebug("hahaha, I got the primary lock! now start to recover server state"); // recover server state while ((err = _state->on_become_leader()) != ERR_OK) { derror("recover server state failed, err = %s, retry ...", err.to_string()); } // create server load balancer // TODO: create per app server load balancer const char* server_load_balancer = dsn_config_get_value_string( "meta_server", "server_load_balancer_type", "simple_stateful_load_balancer", "server_load_balancer provider type" ); _balancer = dsn::utils::factory_store< ::dsn::dist::server_load_balancer>::create( server_load_balancer, PROVIDER_TYPE_MAIN, _state ); _failure_detector->sync_node_state_and_start_service(); ddebug("start meta_service succeed"); return ERR_OK; }
static bool build_client_network_confs( const char* section, /*out*/ network_client_configs& nss, network_client_configs* default_spec) { nss.clear(); const char* keys[128]; int kcapacity = 128; int kcount = dsn_config_get_all_keys(section, keys, &kcapacity); dassert(kcount <= 128, ""); for (int i = 0; i < kcapacity; i++) { std::string k = keys[i]; if (k.length() <= strlen("network.client.")) continue; if (k.substr(0, strlen("network.client.")) != std::string("network.client.")) continue; auto k2 = k.substr(strlen("network.client.")); if (rpc_channel::is_exist(k2.c_str())) { /* ;channel = network_provider_name,buffer_block_size network.client.RPC_CHANNEL_TCP = dsn::tools::asio_network_provider,65536 network.client.RPC_CHANNEL_UDP = dsn::tools::asio_network_provider,65536 */ rpc_channel ch = rpc_channel::from_string(k2.c_str(), RPC_CHANNEL_TCP); // dsn::tools::asio_network_provider,65536 std::list<std::string> vs; std::string v = dsn_config_get_value_string(section, k.c_str(), "", "network channel configuration, e.g., dsn::tools::asio_network_provider,65536"); utils::split_args(v.c_str(), vs, ','); if (vs.size() != 2) { printf("invalid client network specification '%s', should be '$network-factory,$msg-buffer-size'\n", v.c_str() ); return false; } network_client_config ns; ns.factory_name = vs.begin()->c_str(); ns.message_buffer_block_size = atoi(vs.rbegin()->c_str()); if (ns.message_buffer_block_size == 0) { printf("invalid message buffer size specified: '%s'\n", vs.rbegin()->c_str()); return false; } nss[ch] = ns; } else { printf("invalid rpc channel type: %s\n", k2.c_str()); return false; } } if (default_spec) { for (auto& kv : *default_spec) { if (nss.find(kv.first) == nss.end()) { nss[kv.first] = kv.second; } } } return true; }
static bool build_server_network_confs( const char* section, /*out*/ network_server_configs& nss, network_server_configs* default_spec, const std::vector<int>& ports, bool is_template) { nss.clear(); const char* keys[128]; int kcapacity = 128; int kcount = dsn_config_get_all_keys(section, keys, &kcapacity); dassert(kcount <= 128, ""); for (int i = 0; i < kcapacity; i++) { std::string k = keys[i]; if (k.length() <= strlen("network.server.")) continue; if (k.substr(0, strlen("network.server.")) != std::string("network.server.")) continue; auto k2 = k.substr(strlen("network.server.")); std::list<std::string> ks; utils::split_args(k2.c_str(), ks, '.'); if (ks.size() != 2) { printf("invalid network server config '%s', should be like 'network.server.12345.RPC_CHANNEL_TCP' instead\n", k.c_str()); return false; } int port = atoi(ks.begin()->c_str()); auto k3 = *ks.rbegin(); if (is_template) { if (port != 0) { printf("invalid network server configuration '%s'\n", k.c_str()); printf("port must be zero in [apps..default]\n"); printf(" e.g., network.server.0.RPC_CHANNEL_TCP = NET_HDR_DSN, dsn::tools::asio_network_provider,65536\n"); return false; } } else { if (std::find(ports.begin(), ports.end(), port) == ports.end()) { continue; } } if (rpc_channel::is_exist(k3.c_str())) { /* port = 0 for default setting in [apps..default] port.channel = header_format, network_provider_name,buffer_block_size network.server.port().RPC_CHANNEL_TCP = NET_HDR_DSN, dsn::tools::asio_network_provider,65536 network.server.port().RPC_CHANNEL_UDP = NET_HDR_DSN, dsn::tools::asio_network_provider,65536 */ rpc_channel ch = rpc_channel::from_string(k3.c_str(), RPC_CHANNEL_TCP); network_server_config ns(port, ch); // NET_HDR_DSN, dsn::tools::asio_network_provider,65536 std::list<std::string> vs; std::string v = dsn_config_get_value_string(section, k.c_str(), "", "network channel configuration, e.g., NET_HDR_DSN, dsn::tools::asio_network_provider,65536"); utils::split_args(v.c_str(), vs, ','); if (vs.size() != 3) { printf("invalid network specification '%s', should be '$message-format, $network-factory,$msg-buffer-size'\n", v.c_str() ); return false; } if (!network_header_format::is_exist(vs.begin()->c_str())) { printf("invalid network specification, unkown message header format '%s'\n", vs.begin()->c_str() ); return false; } ns.hdr_format = network_header_format(vs.begin()->c_str()); ns.factory_name = *(++vs.begin()); ns.message_buffer_block_size = atoi(vs.rbegin()->c_str()); if (ns.message_buffer_block_size == 0) { printf("invalid message buffer size specified: '%s'\n", vs.rbegin()->c_str()); return false; } nss[ns] = ns; } else { printf("invalid rpc channel type: %s\n", k3.c_str()); return false; } } if (default_spec) { for (auto& kv : *default_spec) { network_server_config cs = kv.second; for (auto& port : ports) { cs.port = port; if (nss.find(cs) == nss.end()) { nss[cs] = cs; } } if (is_template) { cs.port = 0; if (nss.find(cs) == nss.end()) { nss[cs] = cs; } } } } return true; }