Ejemplo n.º 1
0
Archivo: rpc.cpp Proyecto: am11/rDSN
static void send_message(::dsn::rpc_address addr,
                         const std::string& command,
                         int repeat_times,
                         rpc_reply_handler action_on_succeed,
                         rpc_reply_handler action_on_failure)
{
    task_resp_queue q("response.queue");
    for (int i=0; i!=repeat_times; ++i) {
        dsn_message_t request = dsn_msg_create_request(RPC_TEST_STRING_COMMAND);
        ::dsn::marshall(request, command);
        dsn::task_ptr resp_task = ::dsn::rpc::call(
            addr,
            request,
            nullptr,
            [&](error_code err, dsn_message_t request, dsn_message_t response)
            {
                rpc_group_callback(err, request, response, &q, action_on_succeed, action_on_failure);
            }
        );
        q.enqueue(resp_task, 0);
    }
    while (q.count() != 0) {
        task_ptr p = q.dequeue();
        p->wait();
    }
}
Ejemplo n.º 2
0
void replica::send_prepare_message(const dsn_address_t& addr, partition_status status, mutation_ptr& mu, int timeout_milliseconds)
{
    dsn_message_t msg = dsn_msg_create_request(RPC_PREPARE, timeout_milliseconds, gpid_to_hash(get_gpid()));
    replica_configuration rconfig;
    _primary_states.get_replica_config(status, rconfig);

    {
        msg_binary_writer writer(msg);
        marshall(writer, get_gpid());
        marshall(writer, rconfig);
        mu->write_to(writer);
    }

    mu->remote_tasks()[addr] = rpc::call(addr, msg,
                                         this,
                                         std::bind(&replica::on_prepare_reply,
                                                 this,
                                                 std::make_pair(mu, rconfig.status),
                                                 std::placeholders::_1,
                                                 std::placeholders::_2,
                                                 std::placeholders::_3),
                                         gpid_to_hash(get_gpid())
                                        );

    ddebug(
        "%s: mutation %s send_prepare_message to %s:%hu as %s",
        name(), mu->name(),
        addr.name, addr.port,
        enum_to_string(rconfig.status)
    );
}
Ejemplo n.º 3
0
void replica::send_prepare_message(
    ::dsn::rpc_address addr, 
    partition_status status, 
    mutation_ptr& mu, 
    int timeout_milliseconds,
    int64_t learn_signature)
{
    dsn_message_t msg = dsn_msg_create_request(RPC_PREPARE, timeout_milliseconds, gpid_to_hash(get_gpid()));
    replica_configuration rconfig;
    _primary_states.get_replica_config(status, rconfig, learn_signature);

    {
        rpc_write_stream writer(msg);
        marshall(writer, get_gpid());
        marshall(writer, rconfig);
        mu->write_to(writer);
    }
    
    mu->remote_tasks()[addr] = rpc::call(addr, msg,
        this,
        [=](error_code err, dsn_message_t request, dsn_message_t reply)
        {
            on_prepare_reply(std::make_pair(mu, rconfig.status), err, request, reply);
        },
        gpid_to_hash(get_gpid())
        );

    ddebug( 
        "%s: mutation %s send_prepare_message to %s as %s",  
        name(), mu->name(),
        addr.to_string(),
        enum_to_string(rconfig.status)
        );
}
Ejemplo n.º 4
0
/*send rpc*/
dsn::task_ptr replication_app_client_base::query_partition_config(request_context_ptr request)
{
    //dinfo("query_partition_config, gpid:[%s,%d,%d]", _app_name.c_str(), _app_id, request->partition_index);
    dsn_message_t msg = dsn_msg_create_request(RPC_CM_QUERY_PARTITION_CONFIG_BY_INDEX, 0, 0);

    configuration_query_by_index_request req;
    req.app_name = _app_name;
    if(request->partition_index != -1)
    {
        req.partition_indices.push_back(request->partition_index);
    }
    ::marshall(msg, req);

    rpc_address target(_meta_servers);
    return rpc::call(
        target,
        msg,
        this,
        std::bind(&replication_app_client_base::query_partition_configuration_reply,
            this,
            std::placeholders::_1,
            std::placeholders::_2,
            std::placeholders::_3,
            request
            )
        );
}
Ejemplo n.º 5
0
void simple_kv_client_app::send_config_to_meta(const rpc_address& receiver, dsn::replication::config_type::type type, const rpc_address& node)
{
    dsn_message_t req = dsn_msg_create_request(RPC_CM_PROPOSE_BALANCER, 30000);

    configuration_balancer_request request;
    request.gpid = g_default_gpid;
    request.action_list.emplace_back( configuration_proposal_action{receiver, node, type} );
    request.__set_force(true);

    dsn::marshall(req, request);

    dsn_rpc_call_one_way(_meta_server_group.c_addr(), req);
}
Ejemplo n.º 6
0
    bool command_manager::run_command(const safe_string& cmd, const safe_vector<safe_string>& args, /*out*/ safe_string& output)
    {
        command* h = nullptr;
        {
            utils::auto_read_lock l(_lock);
            auto it = _handlers.find(cmd);
            if (it != _handlers.end())
                h = it->second;
        }

        if (h == nullptr)
        {
            output = safe_string("unknown command '") + cmd + "'";
            return false;
        }
        else
        {
            if (h->address.is_invalid() || h->address == dsn::task::get_current_rpc()->primary_address())
            {
                output = h->handler(args);
                return true;
            }
            else
            {
                ::dsn::rpc_read_stream response;
                
                dsn_message_t msg = dsn_msg_create_request(RPC_CLI_CLI_CALL);
                ::dsn::command rcmd;
                rcmd.cmd = cmd.c_str();
                for (auto& e : args)
                {
                    rcmd.arguments.emplace_back(e.c_str());
                }

                ::dsn::marshall(msg, rcmd);
                auto resp = dsn_rpc_call_wait(h->address.c_addr(), msg);
                if (resp != nullptr)
                {
                    std::string o2 = output.c_str();
                    ::dsn::unmarshall(resp, o2);
                    return true;
                }
                else
                {
                    dwarn("cli run for %s is too long, timeout", cmd.c_str());
                    return false;
                }
            }
        }
    }
Ejemplo n.º 7
0
void replica::update_configuration_on_meta_server(config_type type, ::dsn::rpc_address node, partition_configuration& newConfig)
{
    newConfig.last_committed_decree = last_committed_decree();

    if (type != CT_ASSIGN_PRIMARY && type != CT_UPGRADE_TO_PRIMARY)
    {
        dassert (status() == PS_PRIMARY, "");
        dassert (newConfig.ballot == _primary_states.membership.ballot, "");
    }

    // disable 2pc during reconfiguration
    // it is possible to do this only for CT_DOWNGRADE_TO_SECONDARY,
    // but we choose to disable 2pc during all reconfiguration types
    // for simplicity at the cost of certain write throughput
    update_local_configuration_with_no_ballot_change(PS_INACTIVE);
    set_inactive_state_transient(true);

    dsn_message_t msg = dsn_msg_create_request(RPC_CM_UPDATE_PARTITION_CONFIGURATION, 0, 0);
    
    std::shared_ptr<configuration_update_request> request(new configuration_update_request);
    request->config = newConfig;
    request->config.ballot++;
    request->type = type;
    request->node = node;

    ::marshall(msg, *request);

    if (nullptr != _primary_states.reconfiguration_task)
    {
        _primary_states.reconfiguration_task->cancel(true);
    }

    rpc_address target(_stub->_failure_detector->get_servers());
    _primary_states.reconfiguration_task = rpc::call(
        target,
        msg,        
        this,
        std::bind(&replica::on_update_configuration_on_meta_server_reply, this,
        std::placeholders::_1,
        std::placeholders::_2,
        std::placeholders::_3,
        request),
        gpid_to_hash(get_gpid())
        );
}
Ejemplo n.º 8
0
    bool command_manager::run_command(const std::string& cmd, const std::vector<std::string>& args, /*out*/ std::string& output)
    {
        command* h = nullptr;
        {
            utils::auto_read_lock l(_lock);
            auto it = _handlers.find(cmd);
            if (it != _handlers.end())
                h = it->second;
        }

        if (h == nullptr)
        {
            output = std::string("unknown command '") + cmd + "'";
            return false;
        }
        else
        {
            if (h->address.is_invalid() || h->address == dsn::task::get_current_rpc()->primary_address())
            {
                output = h->handler(args);
                return true;
            }
            else
            {
                ::dsn::rpc_read_stream response;
                
                dsn_message_t msg = dsn_msg_create_request(RPC_DSN_CLI_CALL, 0, 0);
                ::marshall(msg, cmd);
                ::marshall(msg, args);
                auto resp = dsn_rpc_call_wait(h->address.c_addr(), msg);
                if (resp != nullptr)
                {
                    response.set_read_msg(resp);
                    unmarshall(response, output);
                    return true;
                }
                else
                {
                    dwarn("cli run for %s is too long, timeout", cmd.c_str());
                    return false;
                }
            }
        }
    }
Ejemplo n.º 9
0
        task_ptr partition_resolver_simple::query_config(int partition_index)
        {
            dinfo("%s.client: start query config, gpid = %d.%d", _app_path.c_str(), _app_id, partition_index);
            auto msg = dsn_msg_create_request(RPC_CM_QUERY_PARTITION_CONFIG_BY_INDEX);

            configuration_query_by_index_request req;
            req.app_name = _app_path.c_str();
            if (partition_index != -1)
            {
                req.partition_indices.push_back(partition_index);
            }
            marshall(msg, req);

            return rpc::call(
                _meta_server,
                msg,
                this,
                [this, partition_index](error_code err, dsn_message_t req, dsn_message_t resp)
                {
                    query_config_reply(err, req, resp, partition_index);
                }
                );
        }