Skip to content

Commit 3d05a6d

Browse files
committed
fix: limit growth of server sessions through lazy acquisition
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
1 parent 56a1b8a commit 3d05a6d

File tree

1 file changed

+14
-5
lines changed

1 file changed

+14
-5
lines changed

lib/core/sessions.js

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ function assertAlive(session, callback) {
4646
* @typedef {Object} SessionId
4747
*/
4848

49+
const kServerSession = Symbol('serverSession');
50+
4951
/**
5052
* A class representing a client session on the server
5153
* WARNING: not meant to be instantiated directly.
@@ -79,8 +81,8 @@ class ClientSession extends EventEmitter {
7981
this.topology = topology;
8082
this.sessionPool = sessionPool;
8183
this.hasEnded = false;
82-
this.serverSession = sessionPool.acquire();
8384
this.clientOptions = clientOptions;
85+
this[kServerSession] = undefined;
8486

8587
this.supports = {
8688
causalConsistency:
@@ -104,6 +106,14 @@ class ClientSession extends EventEmitter {
104106
return this.serverSession.id;
105107
}
106108

109+
get serverSession() {
110+
if (this[kServerSession] == null) {
111+
this[kServerSession] = this.sessionPool.acquire();
112+
}
113+
114+
return this[kServerSession];
115+
}
116+
107117
/**
108118
* Ends this session on the server
109119
*
@@ -125,7 +135,7 @@ class ClientSession extends EventEmitter {
125135

126136
// release the server session back to the pool
127137
this.sessionPool.release(this.serverSession);
128-
this.serverSession = null;
138+
this[kServerSession] = undefined;
129139

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

701-
// mark the last use of this session, and apply the `lsid`
710+
const serverSession = session.serverSession;
702711
serverSession.lastUse = Date.now();
703712
command.lsid = serverSession.id;
704713

0 commit comments

Comments
 (0)