void replica::assign_primary(configuration_update_request& proposal) { dassert(proposal.node == primary_address(), ""); if (status() == PS_PRIMARY) { dwarn( "%s: invalid assgin primary proposal as the node is in %s", name(), enum_to_string(status())); return; } if (proposal.type == CT_UPGRADE_TO_PRIMARY && (status() != PS_SECONDARY || _secondary_states.checkpoint_task != nullptr)) { dwarn( "%s: invalid upgrade to primary proposal as the node is in %s or during checkpointing", name(), enum_to_string(status())); // TODO: tell meta server so new primary is built more quickly return; } proposal.config.primary = primary_address(); replica_helper::remove_node(primary_address(), proposal.config.secondaries); update_configuration_on_meta_server(proposal.type, proposal.node, proposal.config); }
static gpointer sv_to_callback_data (SV * sv, GPerlI11nInvocationInfo * invocation_info) { GSList *l; if (!invocation_info) return NULL; for (l = invocation_info->callback_infos; l != NULL; l = l->next) { GPerlI11nPerlCallbackInfo *callback_info = l->data; if (callback_info->data_pos == ((gint) invocation_info->current_pos)) { dwarn (" user data for Perl callback %p\n", callback_info); attach_perl_callback_data (callback_info, sv); /* If the user did not specify any code and data and if * there is no destroy notify function, then there is * no need for us to pass on our callback info struct * as C user data. Some libraries (e.g., vte) even * assert that the C user data be NULL if the C * function pointer is NULL. */ if (!gperl_sv_is_defined (callback_info->code) && !gperl_sv_is_defined (callback_info->data) && -1 == callback_info->destroy_pos) { dwarn (" handing over NULL"); return NULL; } return callback_info; } } if (invocation_info->is_callback) { GPerlI11nCCallbackInfo *wrapper = INT2PTR (GPerlI11nCCallbackInfo*, SvIV (sv)); dwarn (" user data for C callback %p\n", wrapper); return wrapper->data; }
TEST(tools_hpc, tail_logger_cb) { std::string output; bool ret = dsn::command_manager::instance().run_command("tail-log", output); if(!ret) return; EXPECT_TRUE(strcmp(output.c_str(), "invalid arguments for tail-log command") == 0 ); std::ostringstream in; in << "tail-log 12345 4 1 " << dsn::utils::get_current_tid(); std::this_thread::sleep_for(std::chrono::seconds(3)); dwarn("key:12345"); std::this_thread::sleep_for(std::chrono::seconds(2)); dwarn("key:12345"); output.clear(); dsn::command_manager::instance().run_command(in.str().c_str(), output); EXPECT_TRUE(strstr(output.c_str(), "In total (1) log entries are found between") != nullptr); dsn::command_manager::instance().run_command("tail-log-dump", output); ::dsn::logging_provider* logger = ::dsn::service_engine::fast_instance().logging(); if (logger != nullptr) { logger->flush(); } }
bool failure_detector::end_ping_internal(::dsn::error_code err, const beacon_ack& ack) { /* * the caller of the end_ping_internal should lock necessarily!!! */ uint64_t beacon_send_time = ack.time; auto node = ack.this_node; uint64_t now = now_ms(); master_map::iterator itr = _masters.find(node); if (itr == _masters.end()) { dwarn("received beacon ack without corresponding master, ignore it, " "remote_master[%s], local_worker[%s]", node.to_string(), primary_address().to_string()); return false; } master_record& record = itr->second; if (!ack.allowed) { dwarn("worker rejected, stop sending beacon message, " "remote_master[%s], local_worker[%s]", node.to_string(), primary_address().to_string()); record.rejected = true; record.send_beacon_timer->cancel(true); return false; } if (!is_time_greater_than(beacon_send_time, record.last_send_time_for_beacon_with_ack)) { // out-dated beacon acks, do nothing dinfo("ignore out dated beacon acks"); return false; } // now the ack is applicable if (err != ERR_OK) { dwarn("ping master failed, err=%s", err.to_string()); return true; } // update last_send_time_for_beacon_with_ack record.last_send_time_for_beacon_with_ack = beacon_send_time; record.rejected = false; if (record.is_alive == false && now - record.last_send_time_for_beacon_with_ack <= _lease_milliseconds) { // report master connected report(node, true, true); itr->second.is_alive = true; on_master_connected(node); } return true; }
void hpc_rpc_session::do_read(int sz) { add_ref(); _read_event.callback = [this](int err, uint32_t length, uintptr_t lolp) { //dinfo("WSARecv completed, err = %d, size = %u", err, length); dassert((LPOVERLAPPED)lolp == &_read_event.olp, "must be exact this overlapped"); if (err != ERROR_SUCCESS) { dwarn("WSARecv failed, err = %d", err); on_failure(); } else { int read_next; message_ex* msg = _parser->get_message_on_receive((int)length, read_next); while (msg != nullptr) { this->on_read_completed(msg); msg = _parser->get_message_on_receive(0, read_next); } do_read(read_next); } release_ref(); }; memset(&_read_event.olp, 0, sizeof(_read_event.olp)); WSABUF buf[1]; void* ptr = _parser->read_buffer_ptr((int)sz); int remaining = _parser->read_buffer_capacity(); buf[0].buf = (char*)ptr; buf[0].len = remaining; DWORD bytes = 0; DWORD flag = 0; int rt = WSARecv( _socket, buf, 1, &bytes, &flag, &_read_event.olp, NULL ); if (SOCKET_ERROR == rt && (WSAGetLastError() != ERROR_IO_PENDING)) { dwarn("WSARecv failed, err = %d", ::WSAGetLastError()); release_ref(); on_failure(); } //dinfo("WSARecv called, err = %d", rt); }
void task_queue::enqueue_internal(task* task) { auto& sp = task->spec(); auto throttle_mode = sp.rpc_request_throttling_mode; if (throttle_mode != TM_NONE) { int ac_value = 0; if (_spec->enable_virtual_queue_throttling) { ac_value = _virtual_queue_length; } else { ac_value = count(); } if (throttle_mode == TM_DELAY) { int delay_ms = sp.rpc_request_delayer.delay(ac_value, _spec->queue_length_throttling_threshold); if (delay_ms > 0) { auto rtask = static_cast<rpc_request_task*>(task); rtask->get_request()->io_session->delay_recv(delay_ms); dwarn("too many pending tasks (%d), delay traffic from %s for %d milliseconds", ac_value, rtask->get_request()->header->from_address.to_string(), delay_ms ); } } else { dbg_dassert(TM_REJECT == throttle_mode, "unknow mode %d", (int)throttle_mode); if (ac_value > _spec->queue_length_throttling_threshold) { auto rtask = static_cast<rpc_request_task*>(task); auto resp = rtask->get_request()->create_response(); task::get_current_rpc()->reply(resp, ERR_BUSY); dwarn("too many pending tasks (%d), reject message from %s with trace_id = %016" PRIx64, ac_value, rtask->get_request()->header->from_address.to_string(), rtask->get_request()->header->trace_id ); task->release_ref(); // added in task::enqueue(pool) return; } } } tls_dsn.last_worker_queue_size = increase_count(); enqueue(task); }
error_code hpc_network_provider::start(rpc_channel channel, int port, bool client_only, io_modifer& ctx) { if (_listen_fd != -1) return ERR_SERVICE_ALREADY_RUNNING; _looper = get_io_looper(node(), ctx.queue, ctx.mode); dassert(channel == RPC_CHANNEL_TCP || channel == RPC_CHANNEL_UDP, "invalid given channel %s", channel.to_string()); char hostname[128]; gethostname(hostname, sizeof(hostname)); _address = ::dsn::rpc_address(HOST_TYPE_IPV4, hostname, port); if (!client_only) { struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = htons(port); _listen_fd = create_tcp_socket(&addr); if (_listen_fd == -1) { dassert(false, "cannot create listen socket"); } int forcereuse = 1; if (setsockopt(_listen_fd, SOL_SOCKET, SO_REUSEADDR, (char*)&forcereuse, sizeof(forcereuse)) != 0) { dwarn("setsockopt SO_REUSEDADDR failed, err = %s", strerror(errno)); } if (listen(_listen_fd, SOMAXCONN) != 0) { dwarn("listen failed, err = %s", strerror(errno)); return ERR_NETWORK_START_FAILED; } _accept_event.callback = [this](int err, uint32_t size, uintptr_t lpolp) { this->do_accept(); }; // bind for accept _looper->bind_io_handle((dsn_handle_t)(intptr_t)_listen_fd, &_accept_event.callback, EVFILT_READ, nullptr // network_provider is a global object ); } return ERR_OK; }
void hpc_rpc_session::connect() { if (!try_connecting()) return; _connect_event.callback = [this](int err, uint32_t io_size, uintptr_t lpolp) { //dinfo("ConnectEx completed, err = %d, size = %u", err, io_size); if (err != ERROR_SUCCESS) { dwarn("ConnectEx failed, err = %d", err); this->on_failure(); } else { dinfo("client session %s:%hu connected", _remote_addr.name(), _remote_addr.port() ); set_connected(); on_send_completed(nullptr); do_read(); } this->release_ref(); // added before ConnectEx }; memset(&_connect_event.olp, 0, sizeof(_connect_event.olp)); struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(_remote_addr.ip()); addr.sin_port = htons(_remote_addr.port()); this->add_ref(); // released in _connect_event.callback BOOL rt = s_lpfnConnectEx( _socket, (struct sockaddr*)&addr, (int)sizeof(addr), 0, 0, 0, &_connect_event.olp ); if (!rt && (WSAGetLastError() != ERROR_IO_PENDING)) { dwarn("ConnectEx failed, err = %d", ::WSAGetLastError()); this->release_ref(); on_failure(); } }
static void prepare_invocation_info (GPerlI11nInvocationInfo *iinfo, GICallableInfo *info) { gint orig_n_args; guint i; dwarn ("invoke: %s\n" " n_args: %d\n", g_base_info_get_name (info), g_callable_info_get_n_args (info)); iinfo->interface = info; iinfo->is_function = GI_IS_FUNCTION_INFO (info); iinfo->is_vfunc = GI_IS_VFUNC_INFO (info); iinfo->is_callback = (g_base_info_get_type (info) == GI_INFO_TYPE_CALLBACK); iinfo->is_signal = GI_IS_SIGNAL_INFO (info); dwarn (" is_function = %d, is_vfunc = %d, is_callback = %d\n", iinfo->is_function, iinfo->is_vfunc, iinfo->is_callback); orig_n_args = g_callable_info_get_n_args (info); g_assert (orig_n_args >= 0); iinfo->n_args = (guint) orig_n_args; if (iinfo->n_args) { iinfo->arg_infos = gperl_alloc_temp (sizeof (GITypeInfo*) * iinfo->n_args); iinfo->arg_types = gperl_alloc_temp (sizeof (GITypeInfo*) * iinfo->n_args); iinfo->aux_args = gperl_alloc_temp (sizeof (GIArgument) * iinfo->n_args); } else { iinfo->arg_infos = NULL; iinfo->arg_types = NULL; iinfo->aux_args = NULL; } for (i = 0 ; i < iinfo->n_args ; i++) { iinfo->arg_infos[i] = g_callable_info_get_arg (info, (gint) i); iinfo->arg_types[i] = g_arg_info_get_type (iinfo->arg_infos[i]); } iinfo->return_type_info = g_callable_info_get_return_type (info); iinfo->has_return_value = GI_TYPE_TAG_VOID != g_type_info_get_tag (iinfo->return_type_info); iinfo->return_type_ffi = g_type_info_get_ffi_type (iinfo->return_type_info); iinfo->return_type_transfer = g_callable_info_get_caller_owns (info); iinfo->callback_infos = NULL; iinfo->array_infos = NULL; iinfo->free_after_call = NULL; }
void asio_rpc_session::set_options() { if (_socket->is_open()) { try { boost::asio::socket_base::send_buffer_size option, option2(16 * 1024 * 1024); _socket->get_option(option); int old = option.value(); _socket->set_option(option2); _socket->get_option(option); dinfo("boost asio send buffer size is %u, set as 16MB, now is %u", old, option.value()); boost::asio::socket_base::receive_buffer_size option3, option4(16 * 1024 * 1024); _socket->get_option(option3); old = option3.value(); _socket->set_option(option4); _socket->get_option(option3); dinfo("boost asio recv buffer size is %u, set as 16MB, now is %u", old, option.value()); } catch (std::exception& ex) { dwarn("network session 0x%x:%hu set socket option failed, err = %s", remote_address().ip(), remote_address().port(), ex.what() ); } } }
std::shared_ptr<uri_resolver> uri_resolver_manager::get(rpc_uri_address* uri) const { std::shared_ptr<uri_resolver> ret = nullptr; auto pr = uri->get_uri_components(); if (pr.second.length() == 0) return ret; { utils::auto_read_lock l(_lock); auto it = _resolvers.find(pr.first); if (it != _resolvers.end()) ret = it->second; } if (ret == nullptr) { dwarn( "cannot find uri resolver for uri '%s' with resolver address as '%s', " "please fix it by setting up a uri resolver section in config file, as follows:\r\n" "[uri-resolver.%s]\r\n" "factory = partition-resolver-factory (e.g., partition_resolver_simple)\r\n" "arguments = uri-resolver-arguments (e.g., localhost:34601,localhost:34602)\r\n", uri->uri(), pr.first.c_str(), pr.first.c_str() ); } return ret; }
void meta_server_failure_detector::on_worker_disconnected(const std::vector<end_point>& nodes) { if (!is_primary()) { return; } node_states states; for (auto& n : nodes) { states.push_back(std::make_pair(n, false)); dwarn("client expired: %s:%hu", n.name.c_str(), n.port); } machine_fail_updates pris; _state->set_node_state(states, &pris); for (auto& pri : pris) { dinfo("%d.%d primary node for %s:%hu is gone, update configuration on meta server", pri.first.app_id, pri.first.pidx, pri.second->node.name.c_str(), pri.second->node.port ); _svc->update_configuration(pri.second); } }
void hpc_rpc_session::connect() { if (!try_connecting()) return; dassert(_socket != -1, "invalid given socket handle"); struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(_remote_addr.ip()); addr.sin_port = htons(_remote_addr.port()); int rt = ::connect(_socket, (struct sockaddr*)&addr, (int)sizeof(addr)); int err = errno; dinfo("(s = %d) call connect to %s:%hu, return %d, err = %s", _socket, _remote_addr.name(), _remote_addr.port(), rt, strerror(err) ); if (rt == -1 && err != EINPROGRESS) { dwarn("(s = %d) connect failed, err = %s", _socket, strerror(err)); on_failure(); return; } // bind for connect _looper->bind_io_handle((dsn_handle_t)(intptr_t)_socket, &_ready_event, EVFILT_WRITE, this ); }
void native_linux_aio_provider::get_event() { struct io_event events[1]; int ret; const char* name = ::dsn::tools::get_service_node_name(node()); char buffer[128]; sprintf(buffer, "%s.aio", name); task_worker::set_name(buffer); while (true) { ret = io_getevents(_ctx, 1, 1, events, NULL); if (ret > 0) // should be 1 { dassert(ret == 1, ""); struct iocb *io = events[0].obj; complete_aio(io, static_cast<int>(events[0].res), static_cast<int>(events[0].res2)); } else { dwarn("io_getevents returns %d, you probably want to try on another machine:-(", ret); } } }
static void release_perl_callback (gpointer data) { GPerlI11nPerlCallbackInfo *info = data; dwarn ("info = %p\n", info); /* g_callable_info_free_closure reaches into info->cif, so it needs to * be called before we free it. See * <https://bugzilla.gnome.org/show_bug.cgi?id=652954>. */ if (info->closure) g_callable_info_free_closure (info->interface, info->closure); if (info->cif) g_free (info->cif); if (info->interface) g_base_info_unref ((GIBaseInfo*) info->interface); if (info->code) SvREFCNT_dec (info->code); if (info->data) SvREFCNT_dec (info->data); if (info->sub_name) g_free (info->sub_name); if (info->args_converter) SvREFCNT_dec (info->args_converter); g_free (info); }
void sim_client_session::send(message_ptr& msg) { sim_network_provider* rnet = nullptr; if (!s_switch[task_spec::get(msg->header().local_rpc_code)->rpc_call_channel].get(msg->header().to_address, rnet)) { dwarn("cannot find destination node %s:%d in simulator", msg->header().to_address.name.c_str(), static_cast<int>(msg->header().to_address.port) ); return; } auto server_session = rnet->get_server_session(_net.address()); if (nullptr == server_session) { rpc_client_session_ptr cptr = this; server_session.reset(new sim_server_session(*rnet, _net.address(), cptr)); rnet->on_server_session_accepted(server_session); } message_ptr recv_msg(new message(msg->writer().get_buffer())); recv_msg->header().from_address = msg->header().from_address; recv_msg->header().to_address = msg->header().to_address; server_session->on_recv_request(recv_msg, recv_msg->header().from_address == recv_msg->header().to_address ? 0 : rnet->net_delay_milliseconds() ); }
void meta_server_failure_detector::on_worker_disconnected(const std::vector< ::dsn::rpc_address>& nodes) { if (!is_primary()) { return; } if (!_svc->_started) { return; } node_states states; for (auto& n : nodes) { states.push_back(std::make_pair(n, false)); dwarn("client expired: %s", n.to_string()); } machine_fail_updates pris; _state->set_node_state(states, &pris); for (auto& pri : pris) { dinfo("%d.%d primary node for %s is gone, update configuration on meta server", pri.first.app_id, pri.first.pidx, pri.second->node.to_string() ); _svc->update_configuration_on_machine_failure(pri.second); } }
static void check_wait_task(task *waitee) { lock_checker::check_wait_safety(); // not in worker thread if (task::get_current_worker() == nullptr) return; // caller and callee don't share the same thread pool, if (waitee->spec().type != TASK_TYPE_RPC_RESPONSE && (waitee->spec().pool_code != task::get_current_worker()->pool_spec().pool_code)) return; // callee is empty if (waitee->is_empty()) return; // there are enough concurrency if (!task::get_current_worker()->pool_spec().partitioned && task::get_current_worker()->pool_spec().worker_count > 1) return; dwarn("task %s waits for another task %s sharing the same thread pool " "- will lead to deadlocks easily (e.g., when worker_count = 1 or when the pool " "is partitioned)", task::get_current_task()->spec().code.to_string(), waitee->spec().code.to_string()); }
void net_io::set_options() { if (_socket.is_open()) { try { boost::asio::socket_base::send_buffer_size option, option2(16 * 1024 * 1024); _socket.get_option(option); int old = option.value(); _socket.set_option(option2); _socket.get_option(option); /*ddebug("boost asio send buffer size is %u, set as 16MB, now is %u", old, option.value());*/ boost::asio::socket_base::receive_buffer_size option3, option4(16 * 1024 * 1024); _socket.get_option(option3); old = option3.value(); _socket.set_option(option4); _socket.get_option(option3); /*ddebug("boost asio recv buffer size is %u, set as 16MB, now is %u", old, option.value());*/ } catch (std::exception& ex) { dwarn("network session %s:%d set socket option failed, err = %s", _remote_addr.to_ip_string().c_str(), static_cast<int>(_remote_addr.port), ex.what() ); } } }
error_code hpc_network_provider::start(rpc_channel channel, int port, bool client_only, io_modifer& ctx) { if (_listen_fd != INVALID_SOCKET) return ERR_SERVICE_ALREADY_RUNNING; _looper = get_io_looper(node(), ctx.queue, ctx.mode); dassert(channel == RPC_CHANNEL_TCP || channel == RPC_CHANNEL_UDP, "invalid given channel %s", channel.to_string()); char name[128]; gethostname(name, sizeof(name)); _address = ::dsn::rpc_address(HOST_TYPE_IPV4, name, port); if (!client_only) { struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = htons(port); _listen_fd = create_tcp_socket(&addr); if (_listen_fd == INVALID_SOCKET) { dassert(false, ""); } int forcereuse = 1; if (setsockopt(_listen_fd, SOL_SOCKET, SO_REUSEADDR, (char*)&forcereuse, sizeof(forcereuse)) != 0) { dwarn("setsockopt SO_REUSEDADDR failed, err = %d", ::GetLastError()); } _looper->bind_io_handle((dsn_handle_t)_listen_fd, &_accept_event.callback); if (listen(_listen_fd, SOMAXCONN) != 0) { dwarn("listen failed, err = %d", ::GetLastError()); return ERR_NETWORK_START_FAILED; } do_accept(); } return ERR_OK; }
static void generic_interface_finalize (gpointer iface, gpointer data) { GIInterfaceInfo *info = data; PERL_UNUSED_VAR (iface); dwarn ("releasing interface info\n"); g_base_info_unref ((GIBaseInfo *) info); }
void replica::on_copy_checkpoint_ack(error_code err, std::shared_ptr<replica_configuration>& req, std::shared_ptr<learn_response>& resp) { check_hashed_access(); if (PS_PRIMARY != status()) { _primary_states.checkpoint_task = nullptr; return; } if (err != ERR_OK || resp == nullptr) { dwarn("%s: copy checkpoint from secondary failed, err = %s", name(), err.to_string()); _primary_states.checkpoint_task = nullptr; return; } if (resp->err != ERR_OK) { dinfo("%s: copy checkpoint from secondary failed, err = %s", name(), resp->err.to_string()); _primary_states.checkpoint_task = nullptr; return; } if (resp->state.to_decree_included <= _app->last_durable_decree()) { dinfo("%s: copy checkpoint from secondary skipped, as its decree is not bigger than current durable_decree: %" PRIu64 " vs %" PRIu64 "", name(), resp->state.to_decree_included, _app->last_durable_decree() ); _primary_states.checkpoint_task = nullptr; return; } std::string ldir = utils::filesystem::path_combine( _app->learn_dir(), "checkpoint.copy" ); if (utils::filesystem::path_exists(ldir)) utils::filesystem::remove_path(ldir); _primary_states.checkpoint_task = file::copy_remote_files( resp->address, resp->base_local_dir, resp->state.files, ldir, false, LPC_REPLICA_COPY_LAST_CHECKPOINT_DONE, this, [this, resp](error_code err, size_t sz) { this->on_copy_checkpoint_file_completed(err, sz, resp); }, gpid_to_hash(get_gpid()) ); }
DSN_API void dsn_perf_counter_remove(dsn_handle_t handle) { auto sptr = reinterpret_cast<dsn::perf_counter*>(handle); if (dsn::perf_counters::instance().remove_counter(sptr->full_name())) sptr->release_ref(); else { dwarn("cannot remove counter %s as it is not found in our repo", sptr->full_name()); } }
void load_balancer::explictly_send_proposal(global_partition_id gpid, int role, config_type type) { if (gpid.app_id<=0 || gpid.pidx<0 || role<0) return; configuration_update_request req; { zauto_read_lock l(_state->_lock); if (gpid.app_id>_state->_apps.size()) return; app_state& app = _state->_apps[gpid.app_id-1]; if (gpid.pidx>=app.partition_count) return; req.config = app.partitions[gpid.pidx]; } dsn::rpc_address proposal_receiver; if (!req.config.primary.is_invalid()) proposal_receiver = req.config.primary; else if (!req.config.secondaries.empty()) proposal_receiver = req.config.secondaries[0]; else { dwarn("no replica in partition config"); return; } if (!req.config.primary.is_invalid()) { req.node = req.config.primary; --role; } if (role >= (int)req.config.secondaries.size()) { dwarn("role doesn't exist"); return; } else if (role != -1) req.node = req.config.secondaries[role]; req.type = type; send_proposal(proposal_receiver, req); }
static socket_t create_tcp_socket(sockaddr_in* addr) { socket_t s = INVALID_SOCKET; if ((s = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET) { dwarn("WSASocket failed, err = %d", ::GetLastError()); return INVALID_SOCKET; } int reuse = 1; if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse, sizeof(int)) == -1) { dwarn("setsockopt SO_REUSEADDR failed, err = %s", strerror(errno)); } int nodelay = 1; if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&nodelay, sizeof(int)) != 0) { dwarn("setsockopt TCP_NODELAY failed, err = %d", ::GetLastError()); } int isopt = 1; if (setsockopt(s, SOL_SOCKET, SO_DONTLINGER, (char*)&isopt, sizeof(int)) != 0) { dwarn("setsockopt SO_DONTLINGER failed, err = %d", ::GetLastError()); } int buflen = 8 * 1024 * 1024; if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char*)&buflen, sizeof(buflen)) != 0) { dwarn("setsockopt SO_SNDBUF failed, err = %d", ::GetLastError()); } buflen = 8*1024*1024; if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char*)&buflen, sizeof(buflen)) != 0) { dwarn("setsockopt SO_RCVBUF failed, err = %d", ::GetLastError()); } int keepalive = 1; if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char*)&keepalive, sizeof(keepalive)) != 0) { dwarn("setsockopt SO_KEEPALIVE failed, err = %d", ::GetLastError()); } if (addr != 0) { if (bind(s, (struct sockaddr*)addr, sizeof(*addr)) != 0) { derror("bind failed, err = %d", ::GetLastError()); closesocket(s); return INVALID_SOCKET; } } return s; }
bool failure_detector::switch_master(::dsn::rpc_address from, ::dsn::rpc_address to, uint32_t delay_milliseconds) { /* the caller of switch master shoud lock necessarily to protect _masters */ auto it = _masters.find(from); auto it2 = _masters.find(to); if (it != _masters.end()) { if (it2 != _masters.end()) { dwarn("switch master failed as both are already registered, from[%s], to[%s]", from.to_string(), to.to_string()); return false; } it->second.node = to; it->second.rejected = false; it->second.send_beacon_timer->cancel(true); it->second.send_beacon_timer = tasking::enqueue_timer(LPC_BEACON_SEND, this, [this, to]() { this->send_beacon(to, now_ms()); }, std::chrono::milliseconds(_beacon_interval_milliseconds), 0, std::chrono::milliseconds(delay_milliseconds) ); _masters.insert(std::make_pair(to, it->second)); _masters.erase(from); dinfo("switch master successfully, from[%s], to[%s]", from.to_string(), to.to_string()); } else { dwarn("switch master failed as from node is not registered yet, from[%s], to[%s]", from.to_string(), to.to_string()); return false; } return true; }
void replica::broadcast_group_check() { dassert (nullptr != _primary_states.group_check_task, ""); if (_primary_states.group_check_pending_replies.size() > 0) { dwarn( "%s: %u group check replies are still pending when doing next round check", name(), static_cast<int>(_primary_states.group_check_pending_replies.size()) ); for (auto it = _primary_states.group_check_pending_replies.begin(); it != _primary_states.group_check_pending_replies.end(); it++) { it->second->cancel(true); } _primary_states.group_check_pending_replies.clear(); } for (auto it = _primary_states.statuses.begin(); it != _primary_states.statuses.end(); it++) { if (it->first == primary_address()) continue; end_point addr = it->first; std::shared_ptr<group_check_request> request(new group_check_request); request->app_type = _primary_states.membership.app_type; request->node = addr; _primary_states.get_replica_config(addr, request->config); request->last_committed_decree = last_committed_decree(); request->learner_signature = 0; if (it->second == PS_POTENTIAL_SECONDARY) { auto it2 = _primary_states.learners.find(it->first); dassert (it2 != _primary_states.learners.end(), ""); request->learner_signature = it2->second.signature; } task_ptr callback_task = rpc::call_typed( addr, RPC_GROUP_CHECK, request, this, &replica::on_group_check_reply, gpid_to_hash(get_gpid()) ); _primary_states.group_check_pending_replies[addr] = callback_task; ddebug( "%s: init_group_check for %s:%d", name(), addr.name.c_str(), addr.port ); } }
bool binary_reader::skip(int count) { if (count <= get_remaining_size()) { _ptr += count; _remaining_size -= count; return true; } else { dwarn("read beyond the end of buffer"); return false; } }
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; } } } }
static gpointer sv_to_callback (GIArgInfo * arg_info, GITypeInfo * type_info, SV * sv, GPerlI11nInvocationInfo * invocation_info) { GIBaseInfo *callback_interface_info; GPerlI11nPerlCallbackInfo *callback_info; GIScopeType scope; /* the destroy notify func is handled by _handle_automatic_arg */ dwarn (" Perl callback at %d (%s)\n", invocation_info->current_pos, g_base_info_get_name (arg_info)); callback_interface_info = g_type_info_get_interface (type_info); callback_info = create_perl_callback_closure (callback_interface_info, sv); callback_info->data_pos = g_arg_info_get_closure (arg_info); callback_info->destroy_pos = g_arg_info_get_destroy (arg_info); callback_info->free_after_use = FALSE; g_base_info_unref (callback_interface_info); dwarn (" Perl callback data at %d, destroy at %d\n", callback_info->data_pos, callback_info->destroy_pos); scope = (!gperl_sv_is_defined (sv)) ? GI_SCOPE_TYPE_CALL : g_arg_info_get_scope (arg_info); switch (scope) { case GI_SCOPE_TYPE_CALL: dwarn (" Perl callback has scope 'call'\n"); free_after_call (invocation_info, (GFunc) release_perl_callback, callback_info); break; case GI_SCOPE_TYPE_NOTIFIED: dwarn (" Perl callback has scope 'notified'\n"); /* This case is already taken care of by the notify * stuff above */ break; case GI_SCOPE_TYPE_ASYNC: dwarn (" Perl callback has scope 'async'\n"); /* FIXME: callback_info->free_after_use = TRUE; */ break; default: ccroak ("unhandled scope type %d encountered", g_arg_info_get_scope (arg_info)); } invocation_info->callback_infos = g_slist_prepend (invocation_info->callback_infos, callback_info); dwarn (" returning Perl closure %p from info %p\n", callback_info->closure, callback_info); return callback_info->closure; }