Skip to content

Commit dd187bf

Browse files
authored
Handle when a Sub Millisecond Tx Timeout is specified (#1108)
If a user sets a timeout with a fractional millisecond value it will be rounded up to the next integer value. e.g > 0.1 → 1 > 1.4 → 2.0 > 1.8 → 2.0 A warning that a rounding has taken place should be logged under info level.
1 parent 33f587d commit dd187bf

File tree

16 files changed

+453
-40
lines changed

16 files changed

+453
-40
lines changed

packages/core/src/driver.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ type CreateSession = (args: {
9898
bookmarkManager?: BookmarkManager
9999
notificationFilter?: NotificationFilter
100100
auth?: AuthToken
101+
log: Logger
101102
}) => Session
102103

103104
type CreateQueryExecutor = (createSession: (config: { database?: string, bookmarkManager?: BookmarkManager }) => Session) => QueryExecutor
@@ -827,7 +828,8 @@ class Driver {
827828
fetchSize,
828829
bookmarkManager,
829830
notificationFilter,
830-
auth
831+
auth,
832+
log: this._log
831833
})
832834
}
833835

packages/core/src/integer.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -908,14 +908,18 @@ class Integer {
908908
* @param {!Integer|number|string|bigint|!{low: number, high: number}} val Value
909909
* @param {Object} [opts={}] Configuration options
910910
* @param {boolean} [opts.strictStringValidation=false] Enable strict validation generated Integer.
911+
* @param {boolean} [opts.ceilFloat=false] Enable round up float to the nearest Integer.
911912
* @returns {!Integer}
912913
* @expose
913914
*/
914-
static fromValue (val: Integerable, opts: { strictStringValidation?: boolean} = {}): Integer {
915+
static fromValue (val: Integerable, opts: { strictStringValidation?: boolean, ceilFloat?: boolean } = {}): Integer {
915916
if (val /* is compatible */ instanceof Integer) {
916917
return val
917918
}
918919
if (typeof val === 'number') {
920+
if (opts.ceilFloat === true) {
921+
val = Math.ceil(val)
922+
}
919923
return Integer.fromNumber(val)
920924
}
921925
if (typeof val === 'string') {
@@ -1066,6 +1070,7 @@ const TWO_PWR_24 = Integer.fromInt(TWO_PWR_24_DBL)
10661070
* @param {Mixed} value - The value to use.
10671071
* @param {Object} [opts={}] Configuration options
10681072
* @param {boolean} [opts.strictStringValidation=false] Enable strict validation generated Integer.
1073+
* @param {boolean} [opts.ceilFloat=false] Enable round up float to the nearest Integer.
10691074
* @return {Integer} - An object of type Integer.
10701075
*/
10711076
const int = Integer.fromValue

packages/core/src/internal/tx-config.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import * as util from './util'
2121
import { newError } from '../error'
2222
import Integer, { int } from '../integer'
23+
import { Logger } from './logger'
2324

2425
/**
2526
* Internal holder of the transaction configuration.
@@ -35,9 +36,9 @@ export class TxConfig {
3536
* @constructor
3637
* @param {Object} config the raw configuration object.
3738
*/
38-
constructor (config: any) {
39+
constructor (config: any, log?: Logger) {
3940
assertValidConfig(config)
40-
this.timeout = extractTimeout(config)
41+
this.timeout = extractTimeout(config, log)
4142
this.metadata = extractMetadata(config)
4243
}
4344

@@ -63,10 +64,14 @@ const EMPTY_CONFIG = new TxConfig({})
6364
/**
6465
* @return {Integer|null}
6566
*/
66-
function extractTimeout (config: any): Integer | null {
67+
function extractTimeout (config: any, log?: Logger): Integer | null {
6768
if (util.isObject(config) && config.timeout != null) {
6869
util.assertNumberOrInteger(config.timeout, 'Transaction timeout')
69-
const timeout = int(config.timeout)
70+
if (isTimeoutFloat(config) && log?.isInfoEnabled() === true) {
71+
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
72+
log?.info(`Transaction timeout expected to be an integer, got: ${config.timeout}. The value will be rounded up.`)
73+
}
74+
const timeout = int(config.timeout, { ceilFloat: true })
7075
if (timeout.isNegative()) {
7176
throw newError('Transaction timeout should not be negative')
7277
}
@@ -75,6 +80,10 @@ function extractTimeout (config: any): Integer | null {
7580
return null
7681
}
7782

83+
function isTimeoutFloat (config: any): boolean {
84+
return typeof config.timeout === 'number' && !Number.isInteger(config.timeout)
85+
}
86+
7887
/**
7988
* @return {object|null}
8089
*/

packages/core/src/session.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import ManagedTransaction from './transaction-managed'
3838
import BookmarkManager from './bookmark-manager'
3939
import { Dict } from './record'
4040
import NotificationFilter from './notification-filter'
41+
import { Logger } from './internal/logger'
4142

4243
type ConnectionConsumer = (connection: Connection | null) => any | undefined | Promise<any> | Promise<undefined>
4344
type TransactionWork<T> = (tx: Transaction) => Promise<T> | T
@@ -74,6 +75,7 @@ class Session {
7475
private readonly _results: Result[]
7576
private readonly _bookmarkManager?: BookmarkManager
7677
private readonly _notificationFilter?: NotificationFilter
78+
private readonly _log?: Logger
7779
/**
7880
* @constructor
7981
* @protected
@@ -100,7 +102,8 @@ class Session {
100102
impersonatedUser,
101103
bookmarkManager,
102104
notificationFilter,
103-
auth
105+
auth,
106+
log
104107
}: {
105108
mode: SessionMode
106109
connectionProvider: ConnectionProvider
@@ -113,6 +116,7 @@ class Session {
113116
bookmarkManager?: BookmarkManager
114117
notificationFilter?: NotificationFilter
115118
auth?: AuthToken
119+
log: Logger
116120
}) {
117121
this._mode = mode
118122
this._database = database
@@ -153,6 +157,7 @@ class Session {
153157
this._results = []
154158
this._bookmarkManager = bookmarkManager
155159
this._notificationFilter = notificationFilter
160+
this._log = log
156161
}
157162

158163
/**
@@ -176,7 +181,7 @@ class Session {
176181
parameters
177182
)
178183
const autoCommitTxConfig = (transactionConfig != null)
179-
? new TxConfig(transactionConfig)
184+
? new TxConfig(transactionConfig, this._log)
180185
: TxConfig.empty()
181186

182187
const result = this._run(validatedQuery, params, async connection => {
@@ -279,7 +284,7 @@ class Session {
279284

280285
let txConfig = TxConfig.empty()
281286
if (arg != null) {
282-
txConfig = new TxConfig(arg)
287+
txConfig = new TxConfig(arg, this._log)
283288
}
284289

285290
return this._beginTransaction(this._mode, txConfig)
@@ -385,7 +390,7 @@ class Session {
385390
transactionWork: TransactionWork<T>,
386391
transactionConfig?: TransactionConfig
387392
): Promise<T> {
388-
const config = new TxConfig(transactionConfig)
393+
const config = new TxConfig(transactionConfig, this._log)
389394
return this._runTransaction(ACCESS_MODE_READ, config, transactionWork)
390395
}
391396

@@ -410,7 +415,7 @@ class Session {
410415
transactionWork: TransactionWork<T>,
411416
transactionConfig?: TransactionConfig
412417
): Promise<T> {
413-
const config = new TxConfig(transactionConfig)
418+
const config = new TxConfig(transactionConfig, this._log)
414419
return this._runTransaction(ACCESS_MODE_WRITE, config, transactionWork)
415420
}
416421

@@ -443,7 +448,7 @@ class Session {
443448
transactionWork: ManagedTransactionWork<T>,
444449
transactionConfig?: TransactionConfig
445450
): Promise<T> {
446-
const config = new TxConfig(transactionConfig)
451+
const config = new TxConfig(transactionConfig, this._log)
447452
return this._executeInTransaction(ACCESS_MODE_READ, config, transactionWork)
448453
}
449454

@@ -465,7 +470,7 @@ class Session {
465470
transactionWork: ManagedTransactionWork<T>,
466471
transactionConfig?: TransactionConfig
467472
): Promise<T> {
468-
const config = new TxConfig(transactionConfig)
473+
const config = new TxConfig(transactionConfig, this._log)
469474
return this._executeInTransaction(ACCESS_MODE_WRITE, config, transactionWork)
470475
}
471476

packages/core/test/driver.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,8 @@ describe('Driver', () => {
625625
mode: 'WRITE',
626626
reactive: false,
627627
impersonatedUser: undefined,
628+
// @ts-expect-error
629+
log: driver?._log,
628630
...extra
629631
}
630632
}

0 commit comments

Comments
 (0)