[JAVA-4069] ConnectionPoolSettings.maxConnectionIdleTimeMS/maxConnectionLifeTimeMS uses a non-monotonic timer Created: 16/Mar/21  Updated: 30/Mar/22

Status: Backlog
Project: Java Driver
Component/s: Connection Management
Affects Version/s: 4.3.0
Fix Version/s: None

Type: Bug Priority: Minor - P4
Reporter: Valentin Kavalenka Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
is related to JAVA-4070 ClientSessionClock uses non-monotonic... Backlog
is related to JAVA-4071 ServerSessionPool uses non-monotonic ... Backlog
is related to JAVA-4072 BenchmarkSuite uses non-monotonic tim... Backlog
Backwards Compatibility: Fully Compatible
Documentation Changes: Not Needed

 Description   

General problem explanation

System.currentTimeMillis represents a wall-clock time and therefore is not monotonic, i.e., it is allowed to go backwards: return t1 and after that (in the happens-before order) return t2 < t1. While the lack of monotonicity is not explicitly expressed in the method specification, the fact that it returns wall-clock time and one can set machine time to a past instant (NTP implementations may also do that) implies the lack of monotonicity. As a result, naive attempts to calculate, e.g. timeout expiration, may fail: the expression (currentTime = System.currentTimeMillis()) - startTime > timeout, where timeout is 1000 ms may evaluate to false for about an hour if the machine time is shifted back 1 hour, which misses the timeout for no good reason.

System.nanoTime on the other hand does not represent a wall-clock time (this is explicitly expressed in the specification) and is explicitly allowed to be used for measuring elapsed time.

The Go standard library tries to prevent users from using a non-monotonic timer when measuring elapsed time by hiding both timers behind a single API: https://golang.org/pkg/time/#hdr-Monotonic_Clocks.

Specific problem

Relevant places in the codebase

Proposed solution

UsageTrackingInternalConnection does not need to track wall-clock time in openedAt/lastUsedAt. We can and should use System.nanoTime to detect if maxConnectionIdleTimeMS/maxConnectionLifeTimeMS is exceeded.


Generated at Thu Feb 08 09:01:09 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.