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(); }
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); }
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(); }