Beispiel #1
0
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);
}
Beispiel #2
0
    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");
}
Beispiel #4
0
 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;
     }
 }
Beispiel #5
0
    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());
        }
    }
Beispiel #6
0
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;
}
Beispiel #7
0
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);
}
Beispiel #8
0
    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);
    }
Beispiel #9
0
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();
}
Beispiel #10
0
        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();
        }
Beispiel #11
0
        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;
        }
Beispiel #12
0
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;
}
Beispiel #13
0
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;
}
Beispiel #14
0
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;
}