Skip to content

Commit ff887ac

Browse files
committed
Handle when a Sub Millisecond Tx Timeout is specified
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 02572c2 commit ff887ac

File tree

3 files changed

+77
-4
lines changed

3 files changed

+77
-4
lines changed

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: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ const EMPTY_CONFIG = new TxConfig({})
6666
function extractTimeout (config: any): Integer | null {
6767
if (util.isObject(config) && config.timeout != null) {
6868
util.assertNumberOrInteger(config.timeout, 'Transaction timeout')
69-
const timeout = int(config.timeout)
69+
const timeout = int(config.timeout, { ceilFloat: true })
7070
if (timeout.isNegative()) {
7171
throw newError('Transaction timeout should not be negative')
7272
}

packages/core/test/session.test.ts

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@
1616
* See the License for the specific language governing permissions and
1717
* limitations under the License.
1818
*/
19-
import { ConnectionProvider, Session, Connection, TransactionPromise, Transaction, BookmarkManager, bookmarkManager, NotificationFilter } from '../src'
19+
import { ConnectionProvider, Session, Connection, TransactionPromise, Transaction, BookmarkManager, bookmarkManager, NotificationFilter, int } from '../src'
2020
import { bookmarks } from '../src/internal'
2121
import { ACCESS_MODE_READ, FETCH_ALL } from '../src/internal/constants'
2222
import ManagedTransaction from '../src/transaction-managed'
2323
import { AuthToken } from '../src/types'
2424
import FakeConnection from './utils/connection.fake'
2525
import { validNotificationFilters } from './utils/notification-filters.fixtures'
26+
import fc from 'fast-check'
2627

2728
describe('session', () => {
2829
const systemBookmarks = ['sys:bm01', 'sys:bm02']
@@ -474,6 +475,28 @@ describe('session', () => {
474475
expect.objectContaining({ auth })
475476
)
476477
})
478+
479+
it('should round up sub milliseconds transaction timeouts', async () => {
480+
return await fc.assert(
481+
fc.asyncProperty(
482+
fc.float({ min: 0, noNaN: true }),
483+
async (timeout: number) => {
484+
const connection = mockBeginWithSuccess(newFakeConnection())
485+
486+
const { session } = setupSession({
487+
connection,
488+
beginTx: false,
489+
database: 'neo4j'
490+
})
491+
492+
await session.beginTransaction({ timeout })
493+
494+
expect(connection.seenBeginTransaction[0][0].txConfig.timeout)
495+
.toEqual(int(Math.ceil(timeout)))
496+
}
497+
)
498+
)
499+
})
477500
})
478501

479502
describe('.commit()', () => {
@@ -588,6 +611,29 @@ describe('session', () => {
588611
expect(status.functionCalled).toEqual(true)
589612
expect(run).toHaveBeenCalledWith(query, params)
590613
})
614+
615+
it('should round up sub milliseconds transaction timeouts', async () => {
616+
return await fc.assert(
617+
fc.asyncProperty(
618+
fc.float({ min: 0, noNaN: true }),
619+
async (timeout: number) => {
620+
const connection = mockBeginWithSuccess(newFakeConnection())
621+
const session = newSessionWithConnection(connection, false, FETCH_ALL)
622+
// @ts-expect-error
623+
jest.spyOn(Transaction.prototype, 'run').mockImplementation(async () => await Promise.resolve())
624+
const query = 'RETURN $a'
625+
const params = { a: 1 }
626+
627+
await execute(session)(async (tx: ManagedTransaction) => {
628+
await tx.run(query, params)
629+
}, { timeout })
630+
631+
expect(connection.seenBeginTransaction[0][0].txConfig.timeout)
632+
.toEqual(int(Math.ceil(timeout)))
633+
}
634+
)
635+
)
636+
})
591637
})
592638

593639
describe('.run()', () => {
@@ -893,7 +939,7 @@ describe('session', () => {
893939
})
894940

895941
await session.run('query')
896-
942+
897943
expect(connectionProvider.acquireConnection).toBeCalledWith(
898944
expect.objectContaining({ auth })
899945
)
@@ -918,6 +964,28 @@ describe('session', () => {
918964
expect.objectContaining({ auth })
919965
)
920966
})
967+
968+
it('should round up sub milliseconds transaction timeouts', async () => {
969+
return await fc.assert(
970+
fc.asyncProperty(
971+
fc.float({ min: 0, noNaN: true }),
972+
async (timeout: number) => {
973+
const connection = newFakeConnection()
974+
975+
const { session } = setupSession({
976+
connection,
977+
beginTx: false,
978+
database: 'neo4j'
979+
})
980+
981+
await session.run('query', {}, { timeout })
982+
983+
expect(connection.seenProtocolOptions[0].txConfig.timeout)
984+
.toEqual(int(Math.ceil(timeout)))
985+
}
986+
)
987+
)
988+
})
921989
})
922990
})
923991

0 commit comments

Comments
 (0)