Skip to content

Commit 1fd0244

Browse files
authored
feat(NODE-2843): implement sessions advanceClusterTime method (#2920)
1 parent a9c0de8 commit 1fd0244

File tree

5 files changed

+502
-190
lines changed

5 files changed

+502
-190
lines changed

src/sdam/common.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,16 @@ export interface ClusterTime {
6666
};
6767
}
6868

69-
/** Shared function to determine clusterTime for a given topology */
70-
export function resolveClusterTime(
71-
topology: Topology | ClientSession,
69+
/** Shared function to determine clusterTime for a given topology or session */
70+
export function _advanceClusterTime(
71+
entity: Topology | ClientSession,
7272
$clusterTime: ClusterTime
7373
): void {
74-
if (topology.clusterTime == null) {
75-
topology.clusterTime = $clusterTime;
74+
if (entity.clusterTime == null) {
75+
entity.clusterTime = $clusterTime;
7676
} else {
77-
if ($clusterTime.clusterTime.greaterThan(topology.clusterTime.clusterTime)) {
78-
topology.clusterTime = $clusterTime;
77+
if ($clusterTime.clusterTime.greaterThan(entity.clusterTime.clusterTime)) {
78+
entity.clusterTime = $clusterTime;
7979
}
8080
}
8181
}

src/sdam/topology.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import {
2828
ServerType,
2929
ClusterTime,
3030
TimerQueue,
31-
resolveClusterTime,
31+
_advanceClusterTime,
3232
drainTimerQueue,
3333
clearAndRemoveTimerFrom,
3434
STATE_CLOSED,
@@ -681,7 +681,7 @@ export class Topology extends TypedEventEmitter<TopologyEvents> {
681681
// value of the clusterTime embedded field."
682682
const clusterTime = serverDescription.$clusterTime;
683683
if (clusterTime) {
684-
resolveClusterTime(this, clusterTime);
684+
_advanceClusterTime(this, clusterTime);
685685
}
686686

687687
// If we already know all the information contained in this updated description, then

src/sessions.ts

+30-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { PromiseProvider } from './promise_provider';
22
import { Binary, Long, Timestamp, Document } from './bson';
33
import { ReadPreference } from './read_preference';
44
import { isTransactionCommand, TxnState, Transaction, TransactionOptions } from './transactions';
5-
import { resolveClusterTime, ClusterTime } from './sdam/common';
5+
import { _advanceClusterTime, ClusterTime } from './sdam/common';
66
import { isSharded } from './cmap/wire_protocol/shared';
77
import {
88
MongoError,
@@ -249,6 +249,34 @@ export class ClientSession extends TypedEventEmitter<ClientSessionEvents> {
249249
}
250250
}
251251

252+
/**
253+
* Advances the clusterTime for a ClientSession to the provided clusterTime of another ClientSession
254+
*
255+
* @param clusterTime - the $clusterTime returned by the server from another session in the form of a document containing the `BSON.Timestamp` clusterTime and signature
256+
*/
257+
advanceClusterTime(clusterTime: ClusterTime): void {
258+
if (!clusterTime || typeof clusterTime !== 'object') {
259+
throw new MongoInvalidArgumentError('input cluster time must be an object');
260+
}
261+
if (!clusterTime.clusterTime || clusterTime.clusterTime._bsontype !== 'Timestamp') {
262+
throw new MongoInvalidArgumentError(
263+
'input cluster time "clusterTime" property must be a valid BSON Timestamp'
264+
);
265+
}
266+
if (
267+
!clusterTime.signature ||
268+
clusterTime.signature.hash?._bsontype !== 'Binary' ||
269+
(typeof clusterTime.signature.keyId !== 'number' &&
270+
clusterTime.signature.keyId?._bsontype !== 'Long') // apparently we decode the key to number?
271+
) {
272+
throw new MongoInvalidArgumentError(
273+
'input cluster time must have a valid "signature" property with BSON Binary hash and BSON Long keyId'
274+
);
275+
}
276+
277+
_advanceClusterTime(this, clusterTime);
278+
}
279+
252280
/**
253281
* Used to determine if this session equals another
254282
*
@@ -886,7 +914,7 @@ export function applySession(
886914

887915
export function updateSessionFromResponse(session: ClientSession, document: Document): void {
888916
if (document.$clusterTime) {
889-
resolveClusterTime(session, document.$clusterTime);
917+
_advanceClusterTime(session, document.$clusterTime);
890918
}
891919

892920
if (document.operationTime && session && session.supports.causalConsistency) {

0 commit comments

Comments
 (0)