class KeysCollectionCacheReaderAndUpdater : public KeysCollectionCacheReader {
public:
StatusWith<KeysCollectionDocument> refresh(OperationContext* opCtx) override {
// assumption: users never insert new keys
coll = admin.system.keys;
auto currentTime = getCurrentLogicalTime(opCtx);
// readConcern level local
cursor = coll.find({ purpose: _purpose, expiresAt: { $gt: currentTime }}).sort({ expiresAt: 1 });
// all writes have { w: majority } write concern
if (!cursor.hasNext()) {
currentKeyExpiresAt = currentTime + _keyRotationInterval;
coll.insert({ newKey using currentKeyExpirsAt });
}
else {
currentKeyExpiresAt = cursor.next()["expiresAt"];
}
// Create a new key in advance if we don't have a key on standby after the current one
// expires.
if (!cursor.hasNext()) {
reserveKeyExpiresAt = currentKeyExpiresAt + _keyRotationInterval;
coll.insert({ newKey using reserveKeyExpiresAt });
}
return KeysCollectionCacheReader::refresh(opCtx);
}
private:
std::string _purpose;
};