summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Pulo <kevin.pulo@mongodb.com>2020-07-07 22:02:16 +1000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-07-23 05:57:22 +0000
commit6b5b168edf19e336dacff0a8c54a9dd1f32ed1e2 (patch)
treebf2c72c3d19aecda97bad2f9e314a64f1bde10cf
parent00d90d78e84cdc16a03a2a5173ce797e3c3745b9 (diff)
downloadmongo-6b5b168edf19e336dacff0a8c54a9dd1f32ed1e2.tar.gz
SERVER-49189 pass current cachedValue (and time, if causally consistent) to ReadThroughCache::LookupFn
-rw-r--r--src/mongo/db/auth/authorization_manager_impl.cpp24
-rw-r--r--src/mongo/db/auth/authorization_manager_impl.h8
-rw-r--r--src/mongo/db/read_write_concern_defaults.cpp13
-rw-r--r--src/mongo/util/invalidating_lru_cache.h15
-rw-r--r--src/mongo/util/invalidating_lru_cache_test.cpp16
-rw-r--r--src/mongo/util/net/ssl_manager_openssl.cpp4
-rw-r--r--src/mongo/util/read_through_cache.h34
-rw-r--r--src/mongo/util/read_through_cache_test.cpp181
8 files changed, 197 insertions, 98 deletions
diff --git a/src/mongo/db/auth/authorization_manager_impl.cpp b/src/mongo/db/auth/authorization_manager_impl.cpp
index e793b33f51d..c7c27d3c461 100644
--- a/src/mongo/db/auth/authorization_manager_impl.cpp
+++ b/src/mongo/db/auth/authorization_manager_impl.cpp
@@ -656,16 +656,19 @@ AuthorizationManagerImpl::AuthSchemaVersionCache::AuthSchemaVersionCache(
ServiceContext* service,
ThreadPoolInterface& threadPool,
AuthzManagerExternalState* externalState)
- : ReadThroughCache(
- _mutex,
- service,
- threadPool,
- [this](OperationContext* opCtx, int unusedKey) { return _lookup(opCtx, unusedKey); },
- 1 /* cacheSize */),
+ : ReadThroughCache(_mutex,
+ service,
+ threadPool,
+ [this](OperationContext* opCtx, int key, const ValueHandle& cachedValue) {
+ return _lookup(opCtx, key, cachedValue);
+ },
+ 1 /* cacheSize */),
_externalState(externalState) {}
AuthorizationManagerImpl::AuthSchemaVersionCache::LookupResult
-AuthorizationManagerImpl::AuthSchemaVersionCache::_lookup(OperationContext* opCtx, int unusedKey) {
+AuthorizationManagerImpl::AuthSchemaVersionCache::_lookup(OperationContext* opCtx,
+ int unusedKey,
+ const ValueHandle& unusedCachedValue) {
invariant(unusedKey == 0);
int authzVersion;
@@ -683,8 +686,8 @@ AuthorizationManagerImpl::UserCacheImpl::UserCacheImpl(
: UserCache(_mutex,
service,
threadPool,
- [this](OperationContext* opCtx, const UserRequest& userReq) {
- return _lookup(opCtx, userReq);
+ [this](OperationContext* opCtx, const UserRequest& userReq, UserHandle cachedUser) {
+ return _lookup(opCtx, userReq, cachedUser);
},
cacheSize),
_authSchemaVersionCache(authSchemaVersionCache),
@@ -692,7 +695,8 @@ AuthorizationManagerImpl::UserCacheImpl::UserCacheImpl(
AuthorizationManagerImpl::UserCacheImpl::LookupResult
AuthorizationManagerImpl::UserCacheImpl::_lookup(OperationContext* opCtx,
- const UserRequest& userReq) {
+ const UserRequest& userReq,
+ const UserHandle& unusedCachedUser) {
LOGV2_DEBUG(20238, 1, "Getting user record", "user"_attr = userReq.name);
// Number of times to retry a user document that fetches due to transient AuthSchemaIncompatible
diff --git a/src/mongo/db/auth/authorization_manager_impl.h b/src/mongo/db/auth/authorization_manager_impl.h
index 611aa427662..ba2d214d12a 100644
--- a/src/mongo/db/auth/authorization_manager_impl.h
+++ b/src/mongo/db/auth/authorization_manager_impl.h
@@ -158,7 +158,9 @@ private:
// Even though the dist cache permits for lookup to return boost::none for non-existent
// values, the contract of the authorization manager is that it should throw an exception if
// the value can not be loaded, so if it returns, the value will always be set.
- LookupResult _lookup(OperationContext* opCtx, int unusedKey);
+ LookupResult _lookup(OperationContext* opCtx,
+ int unusedKey,
+ const ValueHandle& unusedCachedValue);
Mutex _mutex =
MONGO_MAKE_LATCH("AuthorizationManagerImpl::AuthSchemaVersionDistCache::_mutex");
@@ -181,7 +183,9 @@ private:
// Even though the dist cache permits for lookup to return boost::none for non-existent
// values, the contract of the authorization manager is that it should throw an exception if
// the value can not be loaded, so if it returns, the value will always be set.
- LookupResult _lookup(OperationContext* opCtx, const UserRequest& user);
+ LookupResult _lookup(OperationContext* opCtx,
+ const UserRequest& user,
+ const UserHandle& unusedCachedUser);
Mutex _mutex = MONGO_MAKE_LATCH("AuthorizationManagerImpl::UserDistCacheImpl::_mutex");
diff --git a/src/mongo/db/read_write_concern_defaults.cpp b/src/mongo/db/read_write_concern_defaults.cpp
index 3c69751348a..5e675f6d627 100644
--- a/src/mongo/db/read_write_concern_defaults.cpp
+++ b/src/mongo/db/read_write_concern_defaults.cpp
@@ -237,12 +237,13 @@ ReadWriteConcernDefaults::~ReadWriteConcernDefaults() = default;
ReadWriteConcernDefaults::Cache::Cache(ServiceContext* service,
ThreadPoolInterface& threadPool,
FetchDefaultsFn fetchDefaultsFn)
- : ReadThroughCache(
- _mutex,
- service,
- threadPool,
- [this](OperationContext* opCtx, Type) { return LookupResult(lookup(opCtx)); },
- 1 /* cacheSize */),
+ : ReadThroughCache(_mutex,
+ service,
+ threadPool,
+ [this](OperationContext* opCtx, Type, const ValueHandle& unusedCachedValue) {
+ return LookupResult(lookup(opCtx));
+ },
+ 1 /* cacheSize */),
_fetchDefaultsFn(std::move(fetchDefaultsFn)) {}
boost::optional<RWConcernDefault> ReadWriteConcernDefaults::Cache::lookup(OperationContext* opCtx) {
diff --git a/src/mongo/util/invalidating_lru_cache.h b/src/mongo/util/invalidating_lru_cache.h
index 60c2341a295..a647a14de89 100644
--- a/src/mongo/util/invalidating_lru_cache.h
+++ b/src/mongo/util/invalidating_lru_cache.h
@@ -404,10 +404,11 @@ public:
}
/**
- * If 'key' is in the store, returns its latest 'timeInStore', which can either be from the time
- * of insertion or from the latest call to 'advanceTimeInStore'. Otherwise, returns Time().
+ * If 'key' is in the store, returns its currently cached value and its latest 'timeInStore',
+ * which can either be from the time of insertion or from the latest call to
+ * 'advanceTimeInStore'. Otherwise, returns a nullptr ValueHandle and Time().
*/
- Time getTimeInStore(const Key& key) {
+ std::pair<ValueHandle, Time> getCachedValueAndTime(const Key& key) {
stdx::lock_guard<Latch> lg(_mutex);
std::shared_ptr<StoredValue> storedValue;
if (auto it = _cache.find(key); it != _cache.end()) {
@@ -417,10 +418,12 @@ public:
storedValue = it->second.lock();
}
- if (storedValue)
- return storedValue->timeInStore;
+ if (storedValue) {
+ auto timeInStore = storedValue->timeInStore;
+ return {ValueHandle(std::move(storedValue)), timeInStore};
+ }
- return Time();
+ return {ValueHandle(nullptr), Time()};
}
/**
diff --git a/src/mongo/util/invalidating_lru_cache_test.cpp b/src/mongo/util/invalidating_lru_cache_test.cpp
index 5d6f53470db..08fcc930486 100644
--- a/src/mongo/util/invalidating_lru_cache_test.cpp
+++ b/src/mongo/util/invalidating_lru_cache_test.cpp
@@ -269,14 +269,18 @@ TEST(InvalidatingLRUCacheTest, CausalConsistencyPreservedForEvictedCheckedOutKey
// list
cache.insertOrAssign(2, TestValue("Key 2 - Value @ TS 20"), Timestamp(20));
- ASSERT_EQ(Timestamp(10), cache.getTimeInStore(1));
+ auto [cachedValueAtTS10, timeInStoreAtTS10] = cache.getCachedValueAndTime(1);
+ ASSERT_EQ(Timestamp(10), timeInStoreAtTS10);
+ ASSERT_EQ("Key 1 - Value @ TS 10", cachedValueAtTS10->value);
ASSERT_EQ("Key 1 - Value @ TS 10", key1ValueAtTS10->value);
ASSERT_EQ("Key 1 - Value @ TS 10", cache.get(1, CacheCausalConsistency::kLatestCached)->value);
ASSERT_EQ("Key 1 - Value @ TS 10", cache.get(1, CacheCausalConsistency::kLatestKnown)->value);
cache.advanceTimeInStore(1, Timestamp(11));
- ASSERT_EQ(Timestamp(11), cache.getTimeInStore(1));
+ auto [cachedValueAtTS11, timeInStoreAtTS11] = cache.getCachedValueAndTime(1);
+ ASSERT_EQ(Timestamp(11), timeInStoreAtTS11);
ASSERT(!key1ValueAtTS10.isValid());
+ ASSERT_EQ("Key 1 - Value @ TS 10", cachedValueAtTS11->value);
ASSERT_EQ("Key 1 - Value @ TS 10", key1ValueAtTS10->value);
ASSERT_EQ("Key 1 - Value @ TS 10", cache.get(1, CacheCausalConsistency::kLatestCached)->value);
ASSERT(!cache.get(1, CacheCausalConsistency::kLatestKnown));
@@ -427,14 +431,18 @@ TEST(InvalidatingLRUCacheTest, CacheSizeZeroCausalConsistency) {
cache.advanceTimeInStore(100, Timestamp(30));
cache.insertOrAssign(100, TestValue("Value @ TS 30"), Timestamp(30));
- ASSERT_EQ(Timestamp(), cache.getTimeInStore(100));
+ auto [cachedValueAtTS30, timeInStoreAtTS30] = cache.getCachedValueAndTime(100);
+ ASSERT_EQ(Timestamp(), timeInStoreAtTS30);
+ ASSERT(!cachedValueAtTS30);
auto valueAtTS30 = cache.insertOrAssignAndGet(100, TestValue("Value @ TS 30"), Timestamp(30));
ASSERT_EQ("Value @ TS 30", cache.get(100, CacheCausalConsistency::kLatestCached)->value);
ASSERT_EQ("Value @ TS 30", cache.get(100, CacheCausalConsistency::kLatestKnown)->value);
cache.advanceTimeInStore(100, Timestamp(35));
- ASSERT_EQ(Timestamp(35), cache.getTimeInStore(100));
+ auto [cachedValueAtTS35, timeInStoreAtTS35] = cache.getCachedValueAndTime(100);
+ ASSERT_EQ(Timestamp(35), timeInStoreAtTS35);
+ ASSERT_EQ("Value @ TS 30", cachedValueAtTS35->value);
ASSERT_EQ("Value @ TS 30", cache.get(100, CacheCausalConsistency::kLatestCached)->value);
ASSERT(!cache.get(100, CacheCausalConsistency::kLatestKnown));
diff --git a/src/mongo/util/net/ssl_manager_openssl.cpp b/src/mongo/util/net/ssl_manager_openssl.cpp
index 8233d0fb472..2d0b1dce93e 100644
--- a/src/mongo/util/net/ssl_manager_openssl.cpp
+++ b/src/mongo/util/net/ssl_manager_openssl.cpp
@@ -964,7 +964,9 @@ public:
}
private:
- static LookupResult _lookup(OperationContext* opCtx, const OCSPCacheKey& key) {
+ static LookupResult _lookup(OperationContext* opCtx,
+ const OCSPCacheKey& key,
+ const ValueHandle& unusedCachedValue) {
// If there is a CRL file, we expect the CRL file to cover the certificate status
// information, and therefore we don't need to make a roundtrip.
if (!getSSLGlobalParams().sslCRLFile.empty()) {
diff --git a/src/mongo/util/read_through_cache.h b/src/mongo/util/read_through_cache.h
index 6a59f803c4b..159b106fcdd 100644
--- a/src/mongo/util/read_through_cache.h
+++ b/src/mongo/util/read_through_cache.h
@@ -97,6 +97,17 @@ protected:
Mutex _cancelTokenMutex = MONGO_MAKE_LATCH("ReadThroughCacheBase::_cancelTokenMutex");
};
+template <typename Result, typename Key, typename Value, typename Time>
+struct ReadThroughCacheLookupFnImpl {
+ using fn = unique_function<Result(
+ OperationContext*, const Key&, const Value& cachedValue, const Time& timeInStore)>;
+};
+
+template <typename Result, typename Key, typename Value>
+struct ReadThroughCacheLookupFnImpl<Result, Key, Value, CacheNotCausallyConsistent> {
+ using fn = unique_function<Result(OperationContext*, const Key&, const Value& cachedValue)>;
+};
+
/**
* Implements an (optionally) causally consistent read-through cache from Key to Value, built on top
* of InvalidatingLRUCache.
@@ -206,7 +217,9 @@ public:
// contains the time that the store returned for the 'value'.
Time t;
};
- using LookupFn = unique_function<LookupResult(OperationContext*, const Key&)>;
+
+ using LookupFn =
+ typename ReadThroughCacheLookupFnImpl<LookupResult, Key, ValueHandle, Time>::fn;
// Exposed publicly so it can be unit-tested indepedently of the usages in this class. Must not
// be used independently.
@@ -247,8 +260,11 @@ public:
return it->second->addWaiter(ul);
// Schedule an asynchronous lookup for the key
+ auto [cachedValue, timeInStore] = _cache.getCachedValueAndTime(key);
auto [it, emplaced] = _inProgressLookups.emplace(
- key, std::make_unique<InProgressLookup>(*this, key, _cache.getTimeInStore(key)));
+ key,
+ std::make_unique<InProgressLookup>(
+ *this, key, ValueHandle(std::move(cachedValue)), timeInStore));
invariant(emplaced);
auto& inProgressLookup = *it->second;
auto sharedFutureToReturn = inProgressLookup.addWaiter(ul);
@@ -498,8 +514,11 @@ private:
template <typename Key, typename Value, typename Time>
class ReadThroughCache<Key, Value, Time>::InProgressLookup {
public:
- InProgressLookup(ReadThroughCache& cache, Key key, Time minTimeInStore)
- : _cache(cache), _key(std::move(key)), _minTimeInStore(std::move(minTimeInStore)) {}
+ InProgressLookup(ReadThroughCache& cache, Key key, ValueHandle cachedValue, Time minTimeInStore)
+ : _cache(cache),
+ _key(std::move(key)),
+ _cachedValue(std::move(cachedValue)),
+ _minTimeInStore(std::move(minTimeInStore)) {}
Future<LookupResult> asyncLookupRound() {
auto [promise, future] = makePromiseFuture<LookupResult>();
@@ -510,7 +529,11 @@ public:
OperationContext * opCtx, const Status& status) mutable noexcept {
promise.setWith([&] {
uassertStatusOK(status);
- return _cache._lookupFn(opCtx, _key);
+ if constexpr (std::is_same_v<Time, CacheNotCausallyConsistent>) {
+ return _cache._lookupFn(opCtx, _key, _cachedValue);
+ } else {
+ return _cache._lookupFn(opCtx, _key, _cachedValue, _minTimeInStore);
+ }
});
}));
@@ -580,6 +603,7 @@ private:
bool _valid{false};
boost::optional<CancelToken> _cancelToken;
+ ValueHandle _cachedValue;
Time _minTimeInStore;
using TimeAndPromiseMap = std::map<Time, std::unique_ptr<SharedPromise<ValueHandle>>>;
diff --git a/src/mongo/util/read_through_cache_test.cpp b/src/mongo/util/read_through_cache_test.cpp
index b11f988ca94..b2b4148c744 100644
--- a/src/mongo/util/read_through_cache_test.cpp
+++ b/src/mongo/util/read_through_cache_test.cpp
@@ -60,9 +60,10 @@ public:
service,
threadPool,
[this, lookupFn = std::move(lookupFn)](OperationContext* opCtx,
- const std::string& key) {
+ const std::string& key,
+ const ValueHandle& cachedValue) {
++countLookups;
- return lookupFn(opCtx, key);
+ return lookupFn(opCtx, key, cachedValue);
},
size) {}
@@ -82,9 +83,11 @@ public:
service,
threadPool,
[this, lookupFn = std::move(lookupFn)](OperationContext* opCtx,
- const std::string& key) {
+ const std::string& key,
+ const ValueHandle& cachedValue,
+ Timestamp timeInStore) {
++countLookups;
- return lookupFn(opCtx, key);
+ return lookupFn(opCtx, key, cachedValue, timeInStore);
},
size) {}
@@ -149,7 +152,8 @@ TEST_F(ReadThroughCacheTest, FetchInvalidateAndRefetch) {
fnTest(CacheWithThreadPool<Cache>(
getServiceContext(),
1,
- [&, nextValue = 0](OperationContext*, const std::string& key) mutable {
+ [&, nextValue = 0](
+ OperationContext*, const std::string& key, const Cache::ValueHandle&) mutable {
ASSERT_EQ("TestKey", key);
return Cache::LookupResult(CachedValue(100 * ++nextValue));
}));
@@ -157,7 +161,10 @@ TEST_F(ReadThroughCacheTest, FetchInvalidateAndRefetch) {
fnTest(CacheWithThreadPool<CausallyConsistentCache>(
getServiceContext(),
1,
- [&, nextValue = 0](OperationContext*, const std::string& key) mutable {
+ [&, nextValue = 0](OperationContext*,
+ const std::string& key,
+ const CausallyConsistentCache::ValueHandle&,
+ const Timestamp& timeInStore) mutable {
ASSERT_EQ("TestKey", key);
++nextValue;
return CausallyConsistentCache::LookupResult(CachedValue(100 * nextValue),
@@ -174,14 +181,16 @@ TEST_F(ReadThroughCacheTest, FailedLookup) {
fnTest(CacheWithThreadPool<Cache>(
getServiceContext(),
1,
- [&](OperationContext*, const std::string& key) -> Cache::LookupResult {
- uasserted(ErrorCodes::InternalError, "Test error");
- }));
+ [&](OperationContext*, const std::string& key, const Cache::ValueHandle&)
+ -> Cache::LookupResult { uasserted(ErrorCodes::InternalError, "Test error"); }));
fnTest(CacheWithThreadPool<CausallyConsistentCache>(
getServiceContext(),
1,
- [&](OperationContext*, const std::string& key) -> CausallyConsistentCache::LookupResult {
+ [&](OperationContext*,
+ const std::string& key,
+ const CausallyConsistentCache::ValueHandle&,
+ const Timestamp& timeInStore) -> CausallyConsistentCache::LookupResult {
uasserted(ErrorCodes::InternalError, "Test error");
}));
}
@@ -209,7 +218,8 @@ TEST_F(ReadThroughCacheTest, InvalidateCacheSizeZeroReissuesLookup) {
fnTest(CacheWithThreadPool<Cache>(
getServiceContext(),
0,
- [&, nextValue = 0](OperationContext*, const std::string& key) mutable {
+ [&, nextValue = 0](
+ OperationContext*, const std::string& key, const Cache::ValueHandle&) mutable {
ASSERT_EQ("TestKey", key);
return Cache::LookupResult(CachedValue(1000 * ++nextValue));
}));
@@ -217,7 +227,10 @@ TEST_F(ReadThroughCacheTest, InvalidateCacheSizeZeroReissuesLookup) {
fnTest(CacheWithThreadPool<CausallyConsistentCache>(
getServiceContext(),
0,
- [&, nextValue = 0](OperationContext*, const std::string& key) mutable {
+ [&, nextValue = 0](OperationContext*,
+ const std::string& key,
+ const CausallyConsistentCache::ValueHandle&,
+ const Timestamp& timeInStore) mutable {
ASSERT_EQ("TestKey", key);
++nextValue;
return CausallyConsistentCache::LookupResult(CachedValue(1000 * nextValue),
@@ -229,13 +242,20 @@ TEST_F(ReadThroughCacheTest, KeyDoesNotExist) {
auto fnTest = [&](auto cache) { ASSERT(!cache.acquire(_opCtx, "TestKey")); };
fnTest(CacheWithThreadPool<Cache>(
- getServiceContext(), 1, [&](OperationContext*, const std::string& key) {
+ getServiceContext(),
+ 1,
+ [&](OperationContext*, const std::string& key, const Cache::ValueHandle&) {
ASSERT_EQ("TestKey", key);
return Cache::LookupResult(boost::none);
}));
fnTest(CacheWithThreadPool<CausallyConsistentCache>(
- getServiceContext(), 1, [&](OperationContext*, const std::string& key) {
+ getServiceContext(),
+ 1,
+ [&](OperationContext*,
+ const std::string& key,
+ const CausallyConsistentCache::ValueHandle&,
+ const Timestamp& timeInStore) {
ASSERT_EQ("TestKey", key);
return CausallyConsistentCache::LookupResult(boost::none, Timestamp(10));
}));
@@ -244,7 +264,12 @@ TEST_F(ReadThroughCacheTest, KeyDoesNotExist) {
TEST_F(ReadThroughCacheTest, CausalConsistency) {
boost::optional<CausallyConsistentCache::LookupResult> nextToReturn;
CacheWithThreadPool<CausallyConsistentCache> cache(
- getServiceContext(), 1, [&](OperationContext*, const std::string& key) {
+ getServiceContext(),
+ 1,
+ [&](OperationContext*,
+ const std::string& key,
+ const CausallyConsistentCache::ValueHandle&,
+ const Timestamp& timeInStore) {
ASSERT_EQ("TestKey", key);
return CausallyConsistentCache::LookupResult(std::move(*nextToReturn));
});
@@ -273,9 +298,12 @@ TEST_F(ReadThroughCacheAsyncTest, SuccessfulInProgressLookupForNotCausallyConsis
ThreadPool threadPool{ThreadPool::Options()};
threadPool.startup();
- Cache cache(getServiceContext(), threadPool, 1, [&](OperationContext*, const std::string& key) {
- return Cache::LookupResult(CachedValue(500));
- });
+ Cache cache(getServiceContext(),
+ threadPool,
+ 1,
+ [&](OperationContext*, const std::string& key, const Cache::ValueHandle&) {
+ return Cache::LookupResult(CachedValue(500));
+ });
// Join threads before destroying cache. This ensure the internal asynchronous processing tasks
// are completed before the cache resources are released.
@@ -284,7 +312,8 @@ TEST_F(ReadThroughCacheAsyncTest, SuccessfulInProgressLookupForNotCausallyConsis
threadPool.join();
});
- Cache::InProgressLookup inProgress(cache, "TestKey", CacheNotCausallyConsistent());
+ Cache::InProgressLookup inProgress(
+ cache, "TestKey", Cache::ValueHandle(), CacheNotCausallyConsistent());
auto future = inProgress.addWaiter(WithLock::withoutLock());
ASSERT(!future.isReady());
@@ -308,9 +337,8 @@ TEST_F(ReadThroughCacheAsyncTest, FailedInProgressLookupForNotCausallyConsistent
Cache cache(getServiceContext(),
threadPool,
1,
- [&](OperationContext*, const std::string& key) -> Cache::LookupResult {
- uasserted(ErrorCodes::InternalError, "Test error");
- });
+ [&](OperationContext*, const std::string& key, const Cache::ValueHandle&)
+ -> Cache::LookupResult { uasserted(ErrorCodes::InternalError, "Test error"); });
// Join threads before destroying cache. This ensure the internal asynchronous processing tasks
// are completed before the cache resources are released.
@@ -319,7 +347,8 @@ TEST_F(ReadThroughCacheAsyncTest, FailedInProgressLookupForNotCausallyConsistent
threadPool.join();
});
- Cache::InProgressLookup inProgress(cache, "TestKey", CacheNotCausallyConsistent());
+ Cache::InProgressLookup inProgress(
+ cache, "TestKey", Cache::ValueHandle(), CacheNotCausallyConsistent());
auto future = inProgress.addWaiter(WithLock::withoutLock());
ASSERT(!future.isReady());
@@ -340,11 +369,14 @@ TEST_F(ReadThroughCacheAsyncTest, AcquireObservesOperationContextDeadline) {
Barrier lookupStartedBarrier(2);
Barrier completeLookupBarrier(2);
- Cache cache(getServiceContext(), threadPool, 1, [&](OperationContext*, const std::string& key) {
- lookupStartedBarrier.countDownAndWait();
- completeLookupBarrier.countDownAndWait();
- return Cache::LookupResult(CachedValue(5));
- });
+ Cache cache(getServiceContext(),
+ threadPool,
+ 1,
+ [&](OperationContext*, const std::string& key, const Cache::ValueHandle&) {
+ lookupStartedBarrier.countDownAndWait();
+ completeLookupBarrier.countDownAndWait();
+ return Cache::LookupResult(CachedValue(5));
+ });
// Join threads before destroying cache. This ensure the internal asynchronous processing tasks
// are completed before the cache resources are released.
@@ -397,12 +429,15 @@ TEST_F(ReadThroughCacheAsyncTest, InvalidateReissuesLookup) {
Barrier lookupStartedBarriers[] = {Barrier{2}, Barrier{2}, Barrier{2}};
Barrier completeLookupBarriers[] = {Barrier{2}, Barrier{2}, Barrier{2}};
- Cache cache(getServiceContext(), threadPool, 1, [&](OperationContext*, const std::string& key) {
- int idx = countLookups.fetchAndAdd(1);
- lookupStartedBarriers[idx].countDownAndWait();
- completeLookupBarriers[idx].countDownAndWait();
- return Cache::LookupResult(CachedValue(idx));
- });
+ Cache cache(getServiceContext(),
+ threadPool,
+ 1,
+ [&](OperationContext*, const std::string& key, const Cache::ValueHandle&) {
+ int idx = countLookups.fetchAndAdd(1);
+ lookupStartedBarriers[idx].countDownAndWait();
+ completeLookupBarriers[idx].countDownAndWait();
+ return Cache::LookupResult(CachedValue(idx));
+ });
// Join threads before destroying cache. This ensure the internal asynchronous processing tasks
// are completed before the cache resources are released.
@@ -447,10 +482,13 @@ TEST_F(ReadThroughCacheAsyncTest, AcquireWithAShutdownThreadPool) {
threadPool.shutdown();
threadPool.join();
- Cache cache(getServiceContext(), threadPool, 1, [&](OperationContext*, const std::string&) {
- FAIL("Should not be called");
- return Cache::LookupResult(boost::none); // Will never be reached
- });
+ Cache cache(getServiceContext(),
+ threadPool,
+ 1,
+ [&](OperationContext*, const std::string&, const Cache::ValueHandle&) {
+ FAIL("Should not be called");
+ return Cache::LookupResult(boost::none); // Will never be reached
+ });
auto future = cache.acquireAsync("TestKey");
ASSERT_THROWS_CODE(future.get(), DBException, ErrorCodes::ShutdownInProgress);
@@ -481,10 +519,13 @@ private:
TEST_F(ReadThroughCacheAsyncTest, AdvanceTimeDuringLookupOfUnCachedKey) {
MockThreadPool threadPool;
boost::optional<CausallyConsistentCache::LookupResult> nextToReturn;
- CausallyConsistentCache cache(
- getServiceContext(), threadPool, 1, [&](OperationContext*, const std::string&) {
- return std::move(*nextToReturn);
- });
+ CausallyConsistentCache cache(getServiceContext(),
+ threadPool,
+ 1,
+ [&](OperationContext*,
+ const std::string&,
+ const CausallyConsistentCache::ValueHandle&,
+ const Timestamp&) { return std::move(*nextToReturn); });
auto futureAtTS100 = cache.acquireAsync("TestKey", CacheCausalConsistency::kLatestKnown);
ASSERT(!futureAtTS100.isReady());
@@ -508,10 +549,13 @@ TEST_F(ReadThroughCacheAsyncTest, AdvanceTimeDuringLookupOfUnCachedKey) {
TEST_F(ReadThroughCacheAsyncTest, KeyDeletedAfterAdvanceTimeInStore) {
MockThreadPool threadPool;
boost::optional<CausallyConsistentCache::LookupResult> nextToReturn;
- CausallyConsistentCache cache(
- getServiceContext(), threadPool, 1, [&](OperationContext*, const std::string&) {
- return std::move(*nextToReturn);
- });
+ CausallyConsistentCache cache(getServiceContext(),
+ threadPool,
+ 1,
+ [&](OperationContext*,
+ const std::string&,
+ const CausallyConsistentCache::ValueHandle&,
+ const Timestamp&) { return std::move(*nextToReturn); });
auto futureAtTS100 = cache.acquireAsync("TestKey", CacheCausalConsistency::kLatestKnown);
nextToReturn.emplace(CachedValue(100), Timestamp(100));
@@ -537,10 +581,13 @@ TEST_F(ReadThroughCacheAsyncTest, KeyDeletedAfterAdvanceTimeInStore) {
TEST_F(ReadThroughCacheAsyncTest, AcquireAsyncAndAdvanceTimeInterleave) {
MockThreadPool threadPool;
boost::optional<CausallyConsistentCache::LookupResult> nextToReturn;
- CausallyConsistentCache cache(
- getServiceContext(), threadPool, 1, [&](OperationContext*, const std::string&) {
- return std::move(*nextToReturn);
- });
+ CausallyConsistentCache cache(getServiceContext(),
+ threadPool,
+ 1,
+ [&](OperationContext*,
+ const std::string&,
+ const CausallyConsistentCache::ValueHandle&,
+ const Timestamp&) { return std::move(*nextToReturn); });
auto futureAtTS100 = cache.acquireAsync("TestKey");
nextToReturn.emplace(CachedValue(100), Timestamp(100));
@@ -573,9 +620,12 @@ TEST_F(ReadThroughCacheAsyncTest, AcquireAsyncAndAdvanceTimeInterleave) {
TEST_F(ReadThroughCacheAsyncTest, InvalidateCalledBeforeLookupTaskExecutes) {
MockThreadPool threadPool;
- Cache cache(getServiceContext(), threadPool, 1, [&](OperationContext*, const std::string&) {
- return Cache::LookupResult(CachedValue(123));
- });
+ Cache cache(getServiceContext(),
+ threadPool,
+ 1,
+ [&](OperationContext*, const std::string&, const Cache::ValueHandle&) {
+ return Cache::LookupResult(CachedValue(123));
+ });
auto future = cache.acquireAsync("TestKey");
cache.invalidateAll();
@@ -605,21 +655,24 @@ TEST_F(ReadThroughCacheAsyncTest, CacheSizeZero) {
fnTest(Cache(getServiceContext(),
threadPool,
0,
- [&, nextValue = 0](OperationContext*, const std::string& key) mutable {
+ [&, nextValue = 0](
+ OperationContext*, const std::string& key, const Cache::ValueHandle&) mutable {
ASSERT_EQ("TestKey", key);
return Cache::LookupResult(CachedValue(100 * ++nextValue));
}));
- fnTest(CausallyConsistentCache(
- getServiceContext(),
- threadPool,
- 0,
- [&, nextValue = 0](OperationContext*, const std::string& key) mutable {
- ASSERT_EQ("TestKey", key);
- ++nextValue;
- return CausallyConsistentCache::LookupResult(CachedValue(100 * nextValue),
- Timestamp(nextValue));
- }));
+ fnTest(CausallyConsistentCache(getServiceContext(),
+ threadPool,
+ 0,
+ [&, nextValue = 0](OperationContext*,
+ const std::string& key,
+ const CausallyConsistentCache::ValueHandle&,
+ const Timestamp&) mutable {
+ ASSERT_EQ("TestKey", key);
+ ++nextValue;
+ return CausallyConsistentCache::LookupResult(
+ CachedValue(100 * nextValue), Timestamp(nextValue));
+ }));
}
} // namespace