diff options
-rw-r--r-- | src/mongo/db/auth/SConscript | 7 | ||||
-rw-r--r-- | src/mongo/db/auth/user_cache_invalidator_job.cpp | 70 | ||||
-rw-r--r-- | src/mongo/db/auth/user_cache_invalidator_job.h | 3 | ||||
-rw-r--r-- | src/mongo/db/auth/user_cache_invalidator_job_parameters.idl | 52 |
4 files changed, 83 insertions, 49 deletions
diff --git a/src/mongo/db/auth/SConscript b/src/mongo/db/auth/SConscript index bc823be0c3e..15b65aa08f3 100644 --- a/src/mongo/db/auth/SConscript +++ b/src/mongo/db/auth/SConscript @@ -329,12 +329,17 @@ env.Library( source=[ 'authz_manager_external_state_s.cpp', 'authz_session_external_state_s.cpp', - 'user_cache_invalidator_job.cpp'], + 'user_cache_invalidator_job.cpp', + env.Idlc('user_cache_invalidator_job_parameters.idl')[0], + ], LIBDEPS=[ 'authservercommon', '$BUILD_DIR/mongo/s/catalog/dist_lock_manager', '$BUILD_DIR/mongo/s/coreshard', ], + LIBDEPS_PRIVATE=[ + '$BUILD_DIR/mongo/idl/server_parameter', + ], ) env.Library( diff --git a/src/mongo/db/auth/user_cache_invalidator_job.cpp b/src/mongo/db/auth/user_cache_invalidator_job.cpp index 360d156b465..b2cf463c3b4 100644 --- a/src/mongo/db/auth/user_cache_invalidator_job.cpp +++ b/src/mongo/db/auth/user_cache_invalidator_job.cpp @@ -40,6 +40,7 @@ #include "mongo/base/status_with.h" #include "mongo/client/connpool.h" #include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/user_cache_invalidator_job_parameters_gen.h" #include "mongo/db/client.h" #include "mongo/db/commands.h" #include "mongo/db/server_parameters.h" @@ -56,43 +57,8 @@ namespace mongo { namespace { -// How often to check with the config servers whether authorization information has changed. -AtomicInt32 userCacheInvalidationIntervalSecs(30); // 30 second default stdx::mutex invalidationIntervalMutex; stdx::condition_variable invalidationIntervalChangedCondition; -Date_t lastInvalidationTime; - -class ExportedInvalidationIntervalParameter - : public ExportedServerParameter<int, ServerParameterType::kStartupAndRuntime> { - using Base = ExportedServerParameter<int, ServerParameterType::kStartupAndRuntime>; - -public: - ExportedInvalidationIntervalParameter() - : Base(ServerParameterSet::getGlobal(), - "userCacheInvalidationIntervalSecs", - &userCacheInvalidationIntervalSecs) {} - - // Don't hide Base::set(const BSONElement&) - using Base::set; - - Status set(const int& newValue) override { - stdx::unique_lock<stdx::mutex> lock(invalidationIntervalMutex); - Status status = Base::set(newValue); - invalidationIntervalChangedCondition.notify_all(); - return status; - } -}; - -MONGO_COMPILER_VARIABLE_UNUSED auto _exportedInterval = - (new ExportedInvalidationIntervalParameter()) - -> withValidator([](const int& potentialNewValue) { - if (potentialNewValue < 1 || potentialNewValue > 86400) { - return Status(ErrorCodes::BadValue, - "userCacheInvalidationIntervalSecs must be between 1 " - "and 86400 (24 hours)"); - } - return Status::OK(); - }); StatusWith<OID> getCurrentCacheGeneration(OperationContext* opCtx) { try { @@ -112,6 +78,12 @@ StatusWith<OID> getCurrentCacheGeneration(OperationContext* opCtx) { } // namespace +Status userCacheInvalidationIntervalSecsNotify(const int&) { + { stdx::lock_guard<stdx::mutex> twiddle(invalidationIntervalMutex); } + invalidationIntervalChangedCondition.notify_all(); + return Status::OK(); +} + UserCacheInvalidator::UserCacheInvalidator(AuthorizationManager* authzManager) : _authzManager(authzManager) {} @@ -142,21 +114,23 @@ void UserCacheInvalidator::initialize(OperationContext* opCtx) { void UserCacheInvalidator::run() { Client::initThread("UserCacheInvalidator"); - lastInvalidationTime = Date_t::now(); - + Date_t previousWake = 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(); + { + stdx::unique_lock<stdx::mutex> lock(invalidationIntervalMutex); + Date_t now; + Date_t wake; + auto shouldWake = [&] { + now = Date_t::now(); + wake = previousWake + Seconds(userCacheInvalidationIntervalSecs.load()); + return now >= wake; + }; + while (!shouldWake()) { + MONGO_IDLE_THREAD_BLOCK; + invalidationIntervalChangedCondition.wait_until(lock, wake.toSystemTimePoint()); + } + previousWake = now; } - lastInvalidationTime = now; - lock.unlock(); if (globalInShutdownDeprecated()) { break; diff --git a/src/mongo/db/auth/user_cache_invalidator_job.h b/src/mongo/db/auth/user_cache_invalidator_job.h index 52958ff246d..e487f59dcde 100644 --- a/src/mongo/db/auth/user_cache_invalidator_job.h +++ b/src/mongo/db/auth/user_cache_invalidator_job.h @@ -27,6 +27,7 @@ * exception statement from all source files in the program, then also delete * it in the license file. */ +#pragma once #include "mongo/bson/oid.h" #include "mongo/util/background.h" @@ -60,4 +61,6 @@ private: OID _previousCacheGeneration; }; +Status userCacheInvalidationIntervalSecsNotify(const int& newValue); + } // namespace mongo diff --git a/src/mongo/db/auth/user_cache_invalidator_job_parameters.idl b/src/mongo/db/auth/user_cache_invalidator_job_parameters.idl new file mode 100644 index 00000000000..3f662facedb --- /dev/null +++ b/src/mongo/db/auth/user_cache_invalidator_job_parameters.idl @@ -0,0 +1,52 @@ +# Copyright (C) 2018-present MongoDB, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the Server Side Public License, version 1, +# as published by MongoDB, Inc. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# Server Side Public License for more details. +# +# You should have received a copy of the Server Side Public License +# along with this program. If not, see +# <http://www.mongodb.com/licensing/server-side-public-license>. +# +# As a special exception, the copyright holders give permission to link the +# code of portions of this program with the OpenSSL library under certain +# conditions as described in each individual source file and distribute +# linked combinations including the program with the OpenSSL library. You +# must comply with the Server Side Public License in all respects for +# all of the code used other than as permitted herein. If you modify file(s) +# with this exception, you may extend this exception to your version of the +# file(s), but you are not obligated to do so. If you do not wish to do so, +# delete this exception statement from your version. If you delete this +# exception statement from all source files in the program, then also delete +# it in the license file. + +global: + cpp_namespace: "mongo" + cpp_includes: + - "mongo/db/auth/user_cache_invalidator_job.h" + +imports: + - "mongo/idl/basic_types.idl" + +server_parameters: + userCacheInvalidationIntervalSecs: + description: > + On a mongos instance, specifies the interval (in seconds) at which the mongos instance + checks to determine whether the in-memory cache of user objects has stale data, and if so, + clears the cache. If there are no changes to user objects, mongos will not clear the cache. + cpp_varname: userCacheInvalidationIntervalSecs + cpp_vartype: AtomicInt32 + set_at: + - startup + - runtime + default: 30 + on_update: userCacheInvalidationIntervalSecsNotify + validator: + gte: 1 + lte: 86400 + |