summaryrefslogtreecommitdiff
path: root/src/mongo/db/logical_session_cache.cpp
diff options
context:
space:
mode:
authorsamantharitter <samantha.ritter@10gen.com>2017-06-27 12:09:40 -0400
committerJason Carey <jcarey@argv.me>2017-07-13 17:40:53 -0400
commite1cae24805e3e7282958ee67a01555dd6ce40039 (patch)
treeebce77d9a502a193784483b2201b65e1a5010d98 /src/mongo/db/logical_session_cache.cpp
parent9a49ee3a03e02597086e577f06a71a0723bc0582 (diff)
downloadmongo-e1cae24805e3e7282958ee67a01555dd6ce40039.tar.gz
SERVER-29610 Allow LogicalSessionIds to contain signed user information
Diffstat (limited to 'src/mongo/db/logical_session_cache.cpp')
-rw-r--r--src/mongo/db/logical_session_cache.cpp78
1 files changed, 51 insertions, 27 deletions
diff --git a/src/mongo/db/logical_session_cache.cpp b/src/mongo/db/logical_session_cache.cpp
index 8aa1eaba802..7474c398159 100644
--- a/src/mongo/db/logical_session_cache.cpp
+++ b/src/mongo/db/logical_session_cache.cpp
@@ -32,13 +32,20 @@
#include "mongo/db/logical_session_cache.h"
+#include "mongo/db/operation_context.h"
#include "mongo/db/server_parameters.h"
+#include "mongo/db/service_context.h"
#include "mongo/util/duration.h"
#include "mongo/util/log.h"
#include "mongo/util/periodic_runner.h"
namespace mongo {
+namespace {
+const auto getLogicalSessionCache =
+ ServiceContext::declareDecoration<std::unique_ptr<LogicalSessionCache>>();
+} // namespace
+
MONGO_EXPORT_STARTUP_SERVER_PARAMETER(logicalSessionRecordCacheSize,
int,
LogicalSessionCache::kLogicalSessionCacheDefaultCapacity);
@@ -55,6 +62,20 @@ constexpr int LogicalSessionCache::kLogicalSessionCacheDefaultCapacity;
constexpr Minutes LogicalSessionCache::kLogicalSessionDefaultTimeout;
constexpr Minutes LogicalSessionCache::kLogicalSessionDefaultRefresh;
+LogicalSessionCache* LogicalSessionCache::get(ServiceContext* service) {
+ return getLogicalSessionCache(service).get();
+}
+
+LogicalSessionCache* LogicalSessionCache::get(OperationContext* ctx) {
+ return get(ctx->getClient()->getServiceContext());
+}
+
+void LogicalSessionCache::set(ServiceContext* service,
+ std::unique_ptr<LogicalSessionCache> sessionCache) {
+ auto& cache = getLogicalSessionCache(service);
+ cache = std::move(sessionCache);
+}
+
LogicalSessionCache::LogicalSessionCache(std::unique_ptr<ServiceLiason> service,
std::unique_ptr<SessionsCollection> collection,
Options options)
@@ -78,42 +99,34 @@ LogicalSessionCache::~LogicalSessionCache() {
}
}
-StatusWith<LogicalSessionRecord::Owner> LogicalSessionCache::getOwner(LogicalSessionId lsid) {
+Status LogicalSessionCache::fetchAndPromote(SignedLogicalSessionId slsid) {
// Search our local cache first
- auto owner = getOwnerFromCache(lsid);
- if (owner.isOK()) {
- return owner;
+ auto promoteRes = promote(slsid);
+ if (promoteRes.isOK()) {
+ return promoteRes;
}
// Cache miss, must fetch from the sessions collection.
- auto res = _sessionsColl->fetchRecord(lsid);
+ auto res = _sessionsColl->fetchRecord(slsid);
// If we got a valid record, add it to our cache.
if (res.isOK()) {
auto& record = res.getValue();
record.setLastUse(_service->now());
+ // Any duplicate records here are actually the same record with different
+ // lastUse times, ignore them.
auto oldRecord = _addToCache(record);
-
- // If we had a conflicting record for this id, and they aren't the same record,
- // it could mean that an interloper called endSession and startSession for the
- // same lsid while we were fetching its record from the sessions collection.
- // This means our session has been written over, do not allow the caller to use it.
- // Note: we could find expired versions of our same record here, but they'll compare equal.
- if (oldRecord && *oldRecord != record) {
- return {ErrorCodes::NoSuchSession, "no matching session record found"};
- }
-
- return record.getSessionOwner();
+ return Status::OK();
}
+ // If we could not get a valid record, return the error.
return res.getStatus();
}
-StatusWith<LogicalSessionRecord::Owner> LogicalSessionCache::getOwnerFromCache(
- LogicalSessionId lsid) {
+Status LogicalSessionCache::promote(SignedLogicalSessionId slsid) {
stdx::unique_lock<stdx::mutex> lk(_cacheMutex);
- auto it = _cache.find(lsid);
+ auto it = _cache.find(slsid.getLsid());
if (it == _cache.end()) {
return {ErrorCodes::NoSuchSession, "no matching session record found in the cache"};
}
@@ -126,13 +139,13 @@ StatusWith<LogicalSessionRecord::Owner> LogicalSessionCache::getOwnerFromCache(
// Update the last use time before returning.
it->second.setLastUse(now);
- return it->second.getSessionOwner();
+ return Status::OK();
}
-Status LogicalSessionCache::startSession(LogicalSessionRecord authoritativeRecord) {
+Status LogicalSessionCache::startSession(SignedLogicalSessionId slsid) {
// Make sure the timestamp makes sense
- auto now = _service->now();
- authoritativeRecord.setLastUse(now);
+ auto authoritativeRecord =
+ LogicalSessionRecord::makeAuthoritativeRecord(slsid, _service->now());
// Attempt to insert into the sessions collection first. This collection enforces
// unique session ids, so it will act as concurrency control for us.
@@ -148,7 +161,7 @@ Status LogicalSessionCache::startSession(LogicalSessionRecord authoritativeRecor
auto oldRecord = _addToCache(authoritativeRecord);
if (oldRecord) {
if (*oldRecord != authoritativeRecord) {
- if (!_isDead(*oldRecord, now)) {
+ if (!_isDead(*oldRecord, _service->now())) {
return {ErrorCodes::DuplicateSession, "session with this id already exists"};
}
}
@@ -157,6 +170,17 @@ Status LogicalSessionCache::startSession(LogicalSessionRecord authoritativeRecor
return Status::OK();
}
+StatusWith<SignedLogicalSessionId> LogicalSessionCache::signLsid(OperationContext* opCtx,
+ LogicalSessionId* id,
+ boost::optional<OID> userId) {
+ return _service->signLsid(opCtx, id, std::move(userId));
+}
+
+Status LogicalSessionCache::validateLsid(OperationContext* opCtx,
+ const SignedLogicalSessionId& slsid) {
+ return _service->validateLsid(opCtx, slsid);
+}
+
void LogicalSessionCache::_refresh() {
LogicalSessionIdSet activeSessions;
LogicalSessionIdSet deadSessions;
@@ -177,9 +201,9 @@ void LogicalSessionCache::_refresh() {
for (auto& it : cacheCopy) {
auto record = it.second;
if (!_isDead(record, now)) {
- activeSessions.insert(record.getLsid());
+ activeSessions.insert(record.getSignedLsid().getLsid());
} else {
- deadSessions.insert(record.getLsid());
+ deadSessions.insert(record.getSignedLsid().getLsid());
}
}
@@ -236,7 +260,7 @@ bool LogicalSessionCache::_isDead(const LogicalSessionRecord& record, Date_t now
boost::optional<LogicalSessionRecord> LogicalSessionCache::_addToCache(
LogicalSessionRecord record) {
stdx::unique_lock<stdx::mutex> lk(_cacheMutex);
- return _cache.add(record.getLsid(), std::move(record));
+ return _cache.add(record.getSignedLsid().getLsid(), std::move(record));
}
} // namespace mongo