void ASIOConnection::refresh(Milliseconds timeout, RefreshCallback cb) { auto op = _impl.get(); _refreshCallback = std::move(cb); // Actually timeout refreshes setTimeout(timeout, [this]() { asio::post(_global->_impl->_io_service, [this] { _impl->connection().stream().cancel(); }); }); // Our pings are isMaster's auto beginStatus = op->beginCommand(makeIsMasterRequest(this), NetworkInterfaceASIO::AsyncCommand::CommandType::kRPC, _hostAndPort); if (!beginStatus.isOK()) { auto cb = std::move(_refreshCallback); cb(this, beginStatus); return; } _global->_impl->_asyncRunCommand( op, [this, op](std::error_code ec, size_t bytes) { cancelTimeout(); auto cb = std::move(_refreshCallback); if (ec) return cb(this, Status(ErrorCodes::HostUnreachable, ec.message())); cb(this, Status::OK()); }); }
void ASIOConnection::refresh(Milliseconds timeout, RefreshCallback cb) { _impl->strand().dispatch([this, timeout, cb] { auto op = _impl.get(); // We clear state transitions because we're re-running a portion of the asio state machine // without entering in startCommand (which would call this for us). op->clearStateTransitions(); _refreshCallback = std::move(cb); // Actually timeout refreshes setTimeout(timeout, [this] { _impl->connection().stream().cancel(); }); // Our pings are isMaster's auto beginStatus = op->beginCommand(makeIsMasterRequest(this), NetworkInterfaceASIO::AsyncCommand::CommandType::kRPC, _hostAndPort); if (!beginStatus.isOK()) { auto cb = std::move(_refreshCallback); cb(this, beginStatus); return; } // If we fail during refresh, the _onFinish function of the AsyncOp will get called. As such // we // need to intercept those calls so we can capture them. This will get cleared out when we // fill // in the real onFinish in startCommand. op->setOnFinish([this](StatusWith<RemoteCommandResponse> failedResponse) { invariant(!failedResponse.isOK()); auto cb = std::move(_refreshCallback); cb(this, failedResponse.getStatus()); }); op->_inRefresh = true; _global->_impl->_asyncRunCommand(op, [this, op](std::error_code ec, size_t bytes) { cancelTimeout(); auto cb = std::move(_refreshCallback); if (ec) return cb(this, Status(ErrorCodes::HostUnreachable, ec.message())); op->_inRefresh = false; cb(this, Status::OK()); }); }); }