void UserCacheInvalidator::run() {
        Client::initThread("UserCacheInvalidatorThread");

        while (true) {
            sleepsecs(userCacheInvalidationIntervalSecs);
            if (inShutdown()) {
                break;
            }

            StatusWith<OID> currentGeneration = getCurrentCacheGeneration();
            if (!currentGeneration.isOK()) {
                if (currentGeneration.getStatus().code() == ErrorCodes::CommandNotFound) {
                    warning() << "_getUserCacheGeneration command not found on config server(s), "
                            "this most likely means you are running an outdated version of mongod "
                            "on the config servers" << std::endl;
                } else {
                    warning() << "An error occurred while fetching current user cache generation "
                            "to check if user cache needs invalidation: " <<
                            currentGeneration.getStatus() << std::endl;
                }
                // When in doubt, invalidate the cache
                _authzManager->invalidateUserCache();
            }

            if (currentGeneration.getValue() != _previousCacheGeneration) {
                log() << "User cache generation changed from " << _previousCacheGeneration <<
                        " to " << currentGeneration.getValue() << "; invalidating user cache" <<
                        std::endl;
                _authzManager->invalidateUserCache();
                _previousCacheGeneration = currentGeneration.getValue();
            }
        }
    }
void UserCacheInvalidator::run() {
    Client::initThread("UserCacheInvalidator");
    lastInvalidationTime = Date_t::now();

    while (true) {
        stdx::unique_lock<stdx::mutex> lock(invalidationIntervalMutex);
        Date_t sleepUntil =
            lastInvalidationTime + Seconds(userCacheInvalidationIntervalSecs.load());
        Date_t now = Date_t::now();
        while (now < sleepUntil) {
            MONGO_IDLE_THREAD_BLOCK;
            invalidationIntervalChangedCondition.wait_until(lock, sleepUntil.toSystemTimePoint());
            sleepUntil = lastInvalidationTime + Seconds(userCacheInvalidationIntervalSecs.load());
            now = Date_t::now();
        }
        lastInvalidationTime = now;
        lock.unlock();

        if (globalInShutdownDeprecated()) {
            break;
        }

        auto opCtx = cc().makeOperationContext();
        StatusWith<OID> currentGeneration = getCurrentCacheGeneration(opCtx.get());
        if (!currentGeneration.isOK()) {
            if (currentGeneration.getStatus().code() == ErrorCodes::CommandNotFound) {
                warning() << "_getUserCacheGeneration command not found on config server(s), "
                             "this most likely means you are running an outdated version of mongod "
                             "on the config servers";
            } else {
                warning() << "An error occurred while fetching current user cache generation "
                             "to check if user cache needs invalidation: "
                          << currentGeneration.getStatus();
            }
            // When in doubt, invalidate the cache
            _authzManager->invalidateUserCache();
            continue;
        }

        if (currentGeneration.getValue() != _previousCacheGeneration) {
            log() << "User cache generation changed from " << _previousCacheGeneration << " to "
                  << currentGeneration.getValue() << "; invalidating user cache";
            _authzManager->invalidateUserCache();
            _previousCacheGeneration = currentGeneration.getValue();
        }
    }
}
    void UserCacheInvalidator::run() {
        Client::initThread("UserCacheInvalidatorThread");
        lastInvalidationTime = Date_t(curTimeMillis64());

        while (true) {
            boost::unique_lock<boost::mutex> lock(invalidationIntervalMutex);
            Date_t sleepUntil = Date_t(
                    lastInvalidationTime.millis + userCacheInvalidationIntervalSecs * 1000);
            Date_t now(curTimeMillis64());
            while (now.millis < sleepUntil.millis) {
                invalidationIntervalChangedCondition.timed_wait(lock,
                                                                Milliseconds(sleepUntil - now));
                sleepUntil = Date_t(
                        lastInvalidationTime.millis + (userCacheInvalidationIntervalSecs * 1000));
                now = Date_t(curTimeMillis64());
            }
            lastInvalidationTime = now;
            lock.unlock();

            if (inShutdown()) {
                break;
            }

            StatusWith<OID> currentGeneration = getCurrentCacheGeneration();
            if (!currentGeneration.isOK()) {
                if (currentGeneration.getStatus().code() == ErrorCodes::CommandNotFound) {
                    warning() << "_getUserCacheGeneration command not found on config server(s), "
                            "this most likely means you are running an outdated version of mongod "
                            "on the config servers" << std::endl;
                } else {
                    warning() << "An error occurred while fetching current user cache generation "
                            "to check if user cache needs invalidation: " <<
                            currentGeneration.getStatus() << std::endl;
                }
                // When in doubt, invalidate the cache
                _authzManager->invalidateUserCache();
            }

            if (currentGeneration.getValue() != _previousCacheGeneration) {
                log() << "User cache generation changed from " << _previousCacheGeneration <<
                        " to " << currentGeneration.getValue() << "; invalidating user cache" <<
                        std::endl;
                _authzManager->invalidateUserCache();
                _previousCacheGeneration = currentGeneration.getValue();
            }
        }
    }
void UserCacheInvalidator::initialize(OperationContext* txn) {
    StatusWith<OID> currentGeneration = getCurrentCacheGeneration(txn);
    if (currentGeneration.isOK()) {
        _previousCacheGeneration = currentGeneration.getValue();
        return;
    }

    if (currentGeneration.getStatus().code() == ErrorCodes::CommandNotFound) {
        warning() << "_getUserCacheGeneration command not found while fetching initial user "
                     "cache generation from the config server(s).  This most likely means you are "
                     "running an outdated version of mongod on the config servers";
    } else {
        warning() << "An error occurred while fetching initial user cache generation from "
                     "config servers: " << currentGeneration.getStatus();
    }
    _previousCacheGeneration = OID();
}
void UserCacheInvalidator::run() {
    Client::initThread("UserCacheInvalidator");
    auto interval = globalInvalidationInterval();
    interval->start();
    while (true) {
        interval->wait();

        if (globalInShutdownDeprecated()) {
            break;
        }

        auto opCtx = cc().makeOperationContext();
        StatusWith<OID> currentGeneration = getCurrentCacheGeneration(opCtx.get());
        if (!currentGeneration.isOK()) {
            if (currentGeneration.getStatus().code() == ErrorCodes::CommandNotFound) {
                warning() << "_getUserCacheGeneration command not found on config server(s), "
                             "this most likely means you are running an outdated version of mongod "
                             "on the config servers";
            } else {
                warning() << "An error occurred while fetching current user cache generation "
                             "to check if user cache needs invalidation: "
                          << currentGeneration.getStatus();
            }
            // When in doubt, invalidate the cache
            try {
                _authzManager->invalidateUserCache(opCtx.get());
            } catch (const DBException& e) {
                warning() << "Error invalidating user cache: " << e.toStatus();
            }
            continue;
        }

        if (currentGeneration.getValue() != _previousCacheGeneration) {
            log() << "User cache generation changed from " << _previousCacheGeneration << " to "
                  << currentGeneration.getValue() << "; invalidating user cache";
            try {
                _authzManager->invalidateUserCache(opCtx.get());
            } catch (const DBException& e) {
                warning() << "Error invalidating user cache: " << e.toStatus();
            }

            _previousCacheGeneration = currentGeneration.getValue();
        }
    }
}