void NetworkInterfaceMock::shutdown() {
    invariant(!inShutdown());

    stdx::unique_lock<stdx::mutex> lk(_mutex);
    invariant(_hasStarted);
    _inShutdown.store(true);
    NetworkOperationList todo;
    todo.splice(todo.end(), _scheduled);
    todo.splice(todo.end(), _unscheduled);
    todo.splice(todo.end(), _processing);
    todo.splice(todo.end(), _blackHoled);

    const Date_t now = _now_inlock();
    _waitingToRunMask |= kExecutorThread;  // Prevents network thread from scheduling.
    lk.unlock();
    for (NetworkOperationIterator iter = todo.begin(); iter != todo.end(); ++iter) {
        iter->setResponse(
            now, {ErrorCodes::ShutdownInProgress, "Shutting down mock network", Milliseconds(0)});
        iter->finishResponse();
    }
    lk.lock();
    invariant(_currentlyRunning == kExecutorThread);
    _currentlyRunning = kNoThread;
    _waitingToRunMask = kNetworkThread;
    _shouldWakeNetworkCondition.notify_one();
}
示例#2
0
void NetworkInterfaceMock::scheduleResponse(NetworkOperationIterator noi,
                                            Date_t when,
                                            const TaskExecutor::ResponseStatus& response) {
    stdx::lock_guard<stdx::mutex> lk(_mutex);
    invariant(_currentlyRunning == kNetworkThread);
    NetworkOperationIterator insertBefore = _scheduled.begin();
    while ((insertBefore != _scheduled.end()) && (insertBefore->getResponseDate() <= when)) {
        ++insertBefore;
    }
    noi->setResponse(when, response);
    _scheduled.splice(insertBefore, _processing, noi);
}
示例#3
0
void NetworkInterfaceMock::startCommand(const TaskExecutor::CallbackHandle& cbHandle,
                                        const RemoteCommandRequest& request,
                                        const RemoteCommandCompletionFn& onFinish) {
    stdx::lock_guard<stdx::mutex> lk(_mutex);
    invariant(!_inShutdown);
    const Date_t now = _now_inlock();
    NetworkOperationIterator insertBefore = _unscheduled.begin();
    while ((insertBefore != _unscheduled.end()) &&
           (insertBefore->getNextConsiderationDate() <= now)) {
        ++insertBefore;
    }
    _unscheduled.insert(insertBefore, NetworkOperation(cbHandle, request, now, onFinish));
}
void NetworkInterfaceMock::requeueAt(NetworkOperationIterator noi, Date_t dontAskUntil) {
    stdx::lock_guard<stdx::mutex> lk(_mutex);
    invariant(_currentlyRunning == kNetworkThread);
    invariant(noi->getNextConsiderationDate() < dontAskUntil);
    invariant(_now_inlock() < dontAskUntil);
    NetworkOperationIterator insertBefore = _unscheduled.begin();
    for (; insertBefore != _unscheduled.end(); ++insertBefore) {
        if (insertBefore->getNextConsiderationDate() >= dontAskUntil) {
            break;
        }
    }
    noi->setNextConsiderationDate(dontAskUntil);
    _unscheduled.splice(insertBefore, _processing, noi);
}
void BaseClonerTest::scheduleNetworkResponse(NetworkOperationIterator noi, const BSONObj& obj) {
    auto net = getNet();
    Milliseconds millis(0);
    RemoteCommandResponse response(obj, millis);
    log() << "Scheduling response to request:" << noi->getDiagnosticString() << " -- resp:" << obj;
    net->scheduleResponse(noi, net->now(), response);
}
void BaseClonerTest::scheduleNetworkResponse(NetworkOperationIterator noi,
                                             ErrorCodes::Error code,
                                             const std::string& reason) {
    auto net = getNet();
    RemoteCommandResponse responseStatus(code, reason);
    log() << "Scheduling error response to request:" << noi->getDiagnosticString()
          << " -- status:" << responseStatus.status.toString();
    net->scheduleResponse(noi, net->now(), responseStatus);
}
void NetworkInterfaceMock::scheduleResponse(NetworkOperationIterator noi,
                                            Date_t when,
                                            const ResponseStatus& response) {
    stdx::lock_guard<stdx::mutex> lk(_mutex);
    invariant(_currentlyRunning == kNetworkThread);
    NetworkOperationIterator insertBefore = _scheduled.begin();
    while ((insertBefore != _scheduled.end()) && (insertBefore->getResponseDate() <= when)) {
        ++insertBefore;
    }

    // If no RemoteCommandResponse was returned (for example, on a simulated network error), then
    // do not attempt to run the metadata hook, since there is no returned metadata.
    if (_metadataHook && response.isOK()) {
        _metadataHook->readReplyMetadata(noi->getRequest().target, response.metadata);
    }

    noi->setResponse(when, response);
    _scheduled.splice(insertBefore, _processing, noi);
}
RemoteCommandRequest NetworkInterfaceMock::scheduleErrorResponse(NetworkOperationIterator noi,
                                                                 Date_t when,
                                                                 const Status& response) {
    scheduleResponse(noi, when, response);
    return noi->getRequest();
}