ResponseStatus NetworkInterfaceImpl::runCommand(
            const ReplicationExecutor::RemoteCommandRequest& request) {

        try {
            BSONObj output;

            StatusWith<int> timeoutStatus = getTimeoutMillis(request.expirationDate, now());
            if (!timeoutStatus.isOK())
                return ResponseStatus(timeoutStatus.getStatus());

            int timeout = timeoutStatus.getValue();
            Timer timer;
            ScopedDbConnection conn(request.target.toString(), timeout);
            conn->runCommand(request.dbname, request.cmdObj, output);
            conn.done();
            return ResponseStatus(Response(output, Milliseconds(timer.millis())));
        }
        catch (const DBException& ex) {
            return ResponseStatus(ex.toStatus());
        }
        catch (const std::exception& ex) {
            return ResponseStatus(
                    ErrorCodes::UnknownError,
                    mongoutils::str::stream() <<
                    "Sending command " << request.cmdObj << " on database " << request.dbname <<
                    " over network to " << request.target.toString() << " received exception " <<
                    ex.what());
        }
    }
    ResponseStatus NetworkInterfaceMock::runCommand(
            const ReplicationExecutor::RemoteCommandRequest& request) {
        boost::unique_lock<boost::mutex> lk(_mutex);
        Date_t wakeupTime = _now + _simulatedNetworkLatencyMillis;
        while (wakeupTime < _now) {
            _timeElapsed.wait(lk);
        }

        StatusWith<int> toStatus = getTimeoutMillis(request.expirationDate, _now);
        if (!toStatus.isOK())
            return ResponseStatus(toStatus.getStatus());

        lk.unlock();
        return _helper(request);
    }
StatusWith<RemoteCommandResponse> RemoteCommandRunnerImpl::runCommand(
    const RemoteCommandRequest& request) {
    try {
        const Date_t requestStartDate = Date_t::now();
        const auto timeoutMillis = getTimeoutMillis(request.expirationDate, requestStartDate);
        if (!timeoutMillis.isOK()) {
            return StatusWith<RemoteCommandResponse>(timeoutMillis.getStatus());
        }

        ConnectionPool::ConnectionPtr conn(
            &_connPool, request.target, requestStartDate, timeoutMillis.getValue());

        BSONObj output;
        BSONObj metadata;

        // If remote server does not support either find or getMore commands, down convert
        // to using DBClientInterface::query()/getMore().
        // Perform down conversion based on wire protocol version.

        // 'commandName' will be an empty string if the command object is an empty BSON
        // document.
        StringData commandName = request.cmdObj.firstElement().fieldNameStringData();
        const auto isFindCmd = commandName == QueryRequest::kFindCommandName;
        const auto isGetMoreCmd = commandName == GetMoreRequest::kGetMoreCommandName;
        const auto isFindOrGetMoreCmd = isFindCmd || isGetMoreCmd;

        // We are using the wire version to check if we need to downconverting find/getMore
        // requests because coincidentally, the find/getMore command is only supported by
        // servers that also accept OP_COMMAND.
        bool supportsFindAndGetMoreCommands = rpc::supportsWireVersionForOpCommandInMongod(
            conn.get()->getMinWireVersion(), conn.get()->getMaxWireVersion());

        if (!isFindOrGetMoreCmd || supportsFindAndGetMoreCommands) {
            rpc::UniqueReply commandResponse =
                conn.get()->runCommandWithMetadata(request.dbname,
                                                   request.cmdObj.firstElementFieldName(),
                                                   request.metadata,
                                                   request.cmdObj);

            output = commandResponse->getCommandReply().getOwned();
            metadata = commandResponse->getMetadata().getOwned();
        } else if (isFindCmd) {
            return runDownconvertedFindCommand(conn.get(), request);
        } else if (isGetMoreCmd) {
            return runDownconvertedGetMoreCommand(conn.get(), request);
        }

        const Date_t requestFinishDate = Date_t::now();
        conn.done(requestFinishDate);

        return StatusWith<RemoteCommandResponse>(
            RemoteCommandResponse(std::move(output),
                                  std::move(metadata),
                                  Milliseconds(requestFinishDate - requestStartDate)));
    } catch (const DBException& ex) {
        return StatusWith<RemoteCommandResponse>(ex.toStatus());
    } catch (const std::exception& ex) {
        return StatusWith<RemoteCommandResponse>(
            ErrorCodes::UnknownError,
            str::stream() << "Sending command " << request.cmdObj << " on database "
                          << request.dbname
                          << " over network to "
                          << request.target.toString()
                          << " received exception "
                          << ex.what());
    }
}