Skip to content

Commit

Permalink
fix: limit growth of server sessions through lazy acquisition
Browse files Browse the repository at this point in the history
Server sessions are no longer acquired at `ClientSession`
instantiation, but rather lazily created at the first access of the
`serverSession` property. This has the effect of deferring the
acquisition to command construction, after a connection has been
checked out during operation execution.

NODE-2552
  • Loading branch information
mbroadst committed Apr 21, 2020
1 parent 56a1b8a commit 3d05a6d
Showing 1 changed file with 14 additions and 5 deletions.
19 changes: 14 additions & 5 deletions lib/core/sessions.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ function assertAlive(session, callback) {
* @typedef {Object} SessionId
*/

const kServerSession = Symbol('serverSession');

/**
* A class representing a client session on the server
* WARNING: not meant to be instantiated directly.
Expand Down Expand Up @@ -79,8 +81,8 @@ class ClientSession extends EventEmitter {
this.topology = topology;
this.sessionPool = sessionPool;
this.hasEnded = false;
this.serverSession = sessionPool.acquire();
this.clientOptions = clientOptions;
this[kServerSession] = undefined;

this.supports = {
causalConsistency:
Expand All @@ -104,6 +106,14 @@ class ClientSession extends EventEmitter {
return this.serverSession.id;
}

get serverSession() {
if (this[kServerSession] == null) {
this[kServerSession] = this.sessionPool.acquire();
}

return this[kServerSession];
}

/**
* Ends this session on the server
*
Expand All @@ -125,7 +135,7 @@ class ClientSession extends EventEmitter {

// release the server session back to the pool
this.sessionPool.release(this.serverSession);
this.serverSession = null;
this[kServerSession] = undefined;

// mark the session as ended, and emit a signal
this.hasEnded = true;
Expand Down Expand Up @@ -692,13 +702,12 @@ function commandSupportsReadConcern(command, options) {
* @return {MongoError|null} An error, if some error condition was met
*/
function applySession(session, command, options) {
const serverSession = session.serverSession;
if (serverSession == null) {
if (session.hasEnded) {
// TODO: merge this with `assertAlive`, did not want to throw a try/catch here
return new MongoError('Cannot use a session that has ended');
}

// mark the last use of this session, and apply the `lsid`
const serverSession = session.serverSession;
serverSession.lastUse = Date.now();
command.lsid = serverSession.id;

Expand Down

0 comments on commit 3d05a6d

Please sign in to comment.