static ::dsn::rpc_address build_group() { ::dsn::rpc_address server_group; server_group.assign_group(dsn_group_build("server_group.test")); for (uint16_t p = TEST_PORT_BEGIN; p<=TEST_PORT_END; ++p) { dsn_group_add(server_group.group_handle(), ::dsn::rpc_address("localhost", p).c_addr()); } dsn_group_set_leader(server_group.group_handle(), ::dsn::rpc_address("localhost", TEST_PORT_BEGIN).c_addr()); return server_group; }
TEST(core, group_address_change_leader) { ::dsn::rpc_address addr = build_group(); error_code rpc_err; auto typed_callback = [addr, &rpc_err](error_code err_code, const std::string& result)->void { rpc_err = err_code; if (ERR_OK == err_code) { ::dsn::rpc_address addr_got; ddebug("talk to others callback, result: %s", result.c_str()); EXPECT_TRUE(addr_got.from_string_ipv4(result.c_str())); EXPECT_EQ(TEST_PORT_END, addr_got.port()); } }; ::dsn::task_ptr resp_task; // not update leader on forwarding addr.group_address()->set_update_leader_automatically(false); dsn_group_set_leader(addr.group_handle(), ::dsn::rpc_address("localhost", TEST_PORT_BEGIN).c_addr()); resp_task = ::dsn::rpc::call(addr, dsn_task_code_t(RPC_TEST_STRING_COMMAND), std::string("expect_talk_to_others"), nullptr, typed_callback); resp_task->wait(); if (rpc_err == ERR_OK) { EXPECT_EQ(::dsn::rpc_address("localhost", TEST_PORT_BEGIN), ::dsn::rpc_address(dsn_group_get_leader(addr.group_handle()))); } // update leader on forwarding addr.group_address()->set_update_leader_automatically(true); dsn_group_set_leader(addr.group_handle(), ::dsn::rpc_address("localhost", TEST_PORT_BEGIN).c_addr()); resp_task = ::dsn::rpc::call(addr, dsn_task_code_t(RPC_TEST_STRING_COMMAND), std::string("expect_talk_to_others"), nullptr, typed_callback); resp_task->wait(); ddebug("addr.leader=%s", ::dsn::rpc_address(dsn_group_get_leader(addr.group_handle())).to_string()); if (rpc_err == ERR_OK) { EXPECT_EQ(TEST_PORT_END, ::dsn::rpc_address(dsn_group_get_leader(addr.group_handle())).port()); } destroy_group(addr); }
replication_failure_detector::replication_failure_detector( replica_stub* stub, std::vector<::dsn::rpc_address>& meta_servers) { _meta_servers.assign_group(dsn_group_build("meta.servers")); _stub = stub; for (auto& s : meta_servers) { dsn_group_add(_meta_servers.group_handle(), s.c_addr()); } dsn_group_set_leader(_meta_servers.group_handle(), meta_servers[random32(0, (uint32_t)meta_servers.size() - 1)].c_addr()); }
TEST(core, send_to_invalid_address) { ::dsn::rpc_address group = build_group(); /* here we assume 10.255.254.253:32766 is not assigned */ dsn_group_set_leader(group.group_handle(), ::dsn::rpc_address("10.255.254.253", 32766).c_addr()); rpc_reply_handler action_on_succeed = [](error_code, dsn_message_t, dsn_message_t resp) { std::string hehe_str; ::unmarshall(resp, hehe_str); EXPECT_TRUE(hehe_str == "hehehe"); }; rpc_reply_handler action_on_failure = [](error_code err, dsn_message_t, dsn_message_t) { EXPECT_TRUE(err != ERR_OK); }; send_message(group, std::string("echo hehehe"), 10, action_on_succeed, action_on_failure); destroy_group(group); }
void replication_failure_detector::end_ping(::dsn::error_code err, const fd::beacon_ack& ack, void* context) { failure_detector::end_ping(err, ack, context); zauto_lock l(_meta_lock); if (dsn_group_is_leader(_meta_servers.group_handle(), ack.this_node.c_addr())) { if (err != ERR_OK) { rpc_address node = dsn_group_next(_meta_servers.group_handle(), ack.this_node.c_addr()); if (ack.this_node != node) { switch_master(ack.this_node, node); } } else if (ack.is_master == false) { if (!ack.primary_node.is_invalid()) { switch_master(ack.this_node, ack.primary_node); } } } else { if (err != ERR_OK) { // nothing to do } else if (ack.is_master == false) { if (!ack.primary_node.is_invalid()) { switch_master(ack.this_node, ack.primary_node); } } else { dsn_group_set_leader(_meta_servers.group_handle(), ack.this_node.c_addr()); } } }