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(); } }
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) ); }
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) ); }
/*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 ) ); }
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); }
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; } } } }
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()) ); }
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; } } } }
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); } ); }