Skip to content

Commit 48ed47e

Browse files
authored
perf(NODE-6525): remove setPrototype and defineProperty from hot path (#4321)
1 parent 1965ed5 commit 48ed47e

File tree

2 files changed

+14
-32
lines changed

2 files changed

+14
-32
lines changed

src/sessions.ts

+13-31
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ export class ClientSession
137137
* initially undefined. Gets set to false when startTransaction is called. When commitTransaction is sent to server, if the commitTransaction succeeds, it is then set to undefined, otherwise, set to true */
138138
commitAttempted?: boolean;
139139
/** @internal */
140-
[kServerSession]: ServerSession | null;
140+
private [kServerSession]: ServerSession | null;
141141
/** @internal */
142142
[kSnapshotTime]?: Timestamp;
143143
/** @internal */
@@ -299,11 +299,8 @@ export class ClientSession
299299
if (serverSession != null) {
300300
// release the server session back to the pool
301301
this.sessionPool.release(serverSession);
302-
// Make sure a new serverSession never makes it onto this ClientSession
303-
Object.defineProperty(this, kServerSession, {
304-
value: ServerSession.clone(serverSession),
305-
writable: false
306-
});
302+
// Store a clone of the server session for reference (debugging)
303+
this[kServerSession] = new ServerSession(serverSession);
307304
}
308305
// mark the session as ended, and emit a signal
309306
this.hasEnded = true;
@@ -973,7 +970,16 @@ export class ServerSession {
973970
isDirty: boolean;
974971

975972
/** @internal */
976-
constructor() {
973+
constructor(cloned?: ServerSession | null) {
974+
if (cloned != null) {
975+
const idBytes = Buffer.allocUnsafe(16);
976+
idBytes.set(cloned.id.id.buffer);
977+
this.id = { id: new Binary(idBytes, cloned.id.id.sub_type) };
978+
this.lastUse = cloned.lastUse;
979+
this.txnNumber = cloned.txnNumber;
980+
this.isDirty = cloned.isDirty;
981+
return;
982+
}
977983
this.id = { id: new Binary(uuidV4(), Binary.SUBTYPE_UUID) };
978984
this.lastUse = now();
979985
this.txnNumber = 0;
@@ -994,30 +1000,6 @@ export class ServerSession {
9941000

9951001
return idleTimeMinutes > sessionTimeoutMinutes - 1;
9961002
}
997-
998-
/**
999-
* @internal
1000-
* Cloning meant to keep a readable reference to the server session data
1001-
* after ClientSession has ended
1002-
*/
1003-
static clone(serverSession: ServerSession): Readonly<ServerSession> {
1004-
const arrayBuffer = new ArrayBuffer(16);
1005-
const idBytes = Buffer.from(arrayBuffer);
1006-
idBytes.set(serverSession.id.id.buffer);
1007-
1008-
const id = new Binary(idBytes, serverSession.id.id.sub_type);
1009-
1010-
// Manual prototype construction to avoid modifying the constructor of this class
1011-
return Object.setPrototypeOf(
1012-
{
1013-
id: { id },
1014-
lastUse: serverSession.lastUse,
1015-
txnNumber: serverSession.txnNumber,
1016-
isDirty: serverSession.isDirty
1017-
},
1018-
ServerSession.prototype
1019-
);
1020-
}
10211003
}
10221004

10231005
/**

test/benchmarks/driverBench/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ benchmarkRunner
9595
args: Object.fromEntries(
9696
Object.entries(MONGODB_CLIENT_OPTIONS).map(([key, value]) => [
9797
key,
98-
typeof value === 'number' ? value | 0 : value ? 1 : 0
98+
typeof value === 'number' ? value : value ? 1 : 0
9999
])
100100
)
101101
},

0 commit comments

Comments
 (0)