feat: move session lastUseTime parameter from PooledSession to SessionImpl class. Fix updation of the parameter for chained RPCs within one transaction.#2704
Conversation
…od while retrying exceptions in unit tests. * For details on issue see - googleapis#2206
fix: prevent illegal negative timeout values into thread sleep() method while retrying exceptions in unit tests.
…ssionImpl class. Fix updation of the parameter for chained RPCs within one transaction.
…nPoolMaintainerTest.
…t. Add a couple of unit tests for testing the new behaviour.
…Fix the unit test to test this change.
| private QueryOptions defaultQueryOptions = SpannerOptions.Builder.DEFAULT_QUERY_OPTIONS; | ||
| private ExecutorProvider executorProvider; | ||
|
|
||
| private Clock clock; |
There was a problem hiding this comment.
nit: maybe set this by default to = new Clock() and remove the null check in the AbstractReadContext constructor?
There was a problem hiding this comment.
Sure, this is the clock field within the builder class. I have set it to = new Clock() by default at the member definition (L402)
There was a problem hiding this comment.
I actually meant setting this one (so Builder.clock) by default to = new Clock(). That way, the clock in the AbstractReadContext can be final.
| this.defaultQueryOptions = builder.defaultQueryOptions; | ||
| this.span = builder.span; | ||
| this.executorProvider = builder.executorProvider; | ||
| this.clock = builder.clock == null ? new Clock() : builder.clock; |
There was a problem hiding this comment.
nit: see above, we could remove this null check by setting a default in the builder. Otherwise, prefer the use of com.google.common.base.MoreObjects.firstNonNull(..)
There was a problem hiding this comment.
Using this.clock = firstNonNull(builder.clock, this.clock);
| Options.priority(RpcPriority.HIGH))) { | ||
| while (resultSet.next()) {} | ||
| } | ||
| poolMaintainerClock.currentTimeMillis += Duration.ofMillis(2050).toMillis(); |
There was a problem hiding this comment.
Just to be sure: Because the IdleTimeThreshold is 3 seconds, this means that no session will be cleaned up, right?
There was a problem hiding this comment.
Without the code change, this unit test was failing. We are asserting the number of sessions removed at the end.
assertEquals(0, client.pool.numLeakedSessionsRemoved());
In this test, we have two read RPCs executed. After the first RPC we advance the clock by 1050ms and after the second RPC we advance the clock by 2050ms. This means the overall transaction took > 3s. Hence the current logic would recycle the session thinking its a long running transaction. This is exactly the bug we want to fix.
Post making the code changes, we are ensuring that the session's lastUseTime is getting correctly updated per RPC. And hence, we won't be recycling this session. This again gets tested through the assert statement.
There was a problem hiding this comment.
Thanks for the detailed explanation, that sounds good to me.
| } | ||
|
|
||
| @Override | ||
| public void prepareReadWriteTransaction() { |
There was a problem hiding this comment.
Probably for a different PR, but this seems like a left-over from before InlineBeginTransaction.
…redundant updates from SessionPool class.
… more unit tests.
olavloite
left a comment
There was a problem hiding this comment.
LGTM, with a minor nit on the Builder classes for AbstractReadContext and TransactionContext
| private QueryOptions defaultQueryOptions = SpannerOptions.Builder.DEFAULT_QUERY_OPTIONS; | ||
| private ExecutorProvider executorProvider; | ||
|
|
||
| private Clock clock; |
There was a problem hiding this comment.
I actually meant setting this one (so Builder.clock) by default to = new Clock(). That way, the clock in the AbstractReadContext can be final.
| private final int defaultPrefetchChunks; | ||
| private final QueryOptions defaultQueryOptions; | ||
|
|
||
| private Clock clock = new Clock(); |
There was a problem hiding this comment.
See above, I think this can be made final
| Options.priority(RpcPriority.HIGH))) { | ||
| while (resultSet.next()) {} | ||
| } | ||
| poolMaintainerClock.currentTimeMillis += Duration.ofMillis(2050).toMillis(); |
There was a problem hiding this comment.
Thanks for the detailed explanation, that sounds good to me.
…ansactionRunnerImpl.java Co-authored-by: Knut Olav Løite <[email protected]>
…ansactionRunnerImpl.java Co-authored-by: Knut Olav Løite <[email protected]>
…ansactionRunnerImpl.java Co-authored-by: Knut Olav Løite <[email protected]>
🤖 I have created a release *beep* *boop* --- ## [6.53.0](https://togithub.com/googleapis/java-spanner/compare/v6.52.1...v6.53.0) (2023-11-06) ### Features * Move session lastUseTime parameter from PooledSession to SessionImpl class. Fix updation of the parameter for chained RPCs within one transaction. ([#2704](https://togithub.com/googleapis/java-spanner/issues/2704)) ([e75a281](https://togithub.com/googleapis/java-spanner/commit/e75a2818124621a3ab837151a8e1094fa6c3b8f3)) * Rely on graal-sdk version declaration from property in java-shared-config ([#2696](https://togithub.com/googleapis/java-spanner/issues/2696)) ([cfab83a](https://togithub.com/googleapis/java-spanner/commit/cfab83ad3bd1a026e0b3da5a4cc2154b0f8c3ddf)) ### Bug Fixes * Prevent illegal negative timeout values into thread sleep() method in ITTransactionManagerTest. ([#2715](https://togithub.com/googleapis/java-spanner/issues/2715)) ([1c26cf6](https://togithub.com/googleapis/java-spanner/commit/1c26cf60efa1b98203af9b21a47e37c8fb1e0e97)) ### Dependencies * Update dependency com.google.cloud:google-cloud-shared-dependencies to v3.19.0 ([#2719](https://togithub.com/googleapis/java-spanner/issues/2719)) ([e320753](https://togithub.com/googleapis/java-spanner/commit/e320753b2bd125f94775db9c71a4b7803fa49c38)) * Update dependency com.google.cloud:google-cloud-trace to v2.28.0 ([#2670](https://togithub.com/googleapis/java-spanner/issues/2670)) ([078b7ca](https://togithub.com/googleapis/java-spanner/commit/078b7ca95548ac984c79d29197032b3f813abbcf)) * Update dependency com.google.cloud:google-cloud-trace to v2.29.0 ([#2714](https://togithub.com/googleapis/java-spanner/issues/2714)) ([b400eca](https://togithub.com/googleapis/java-spanner/commit/b400ecabb9fa6f262befa903163746fac2c7c15e)) * Update dependency commons-cli:commons-cli to v1.6.0 ([#2710](https://togithub.com/googleapis/java-spanner/issues/2710)) ([e3e8f6a](https://togithub.com/googleapis/java-spanner/commit/e3e8f6ac82d827280299038d3962fe66b110e0c4)) * Update dependency commons-io:commons-io to v2.15.0 ([#2712](https://togithub.com/googleapis/java-spanner/issues/2712)) ([a5f59aa](https://togithub.com/googleapis/java-spanner/commit/a5f59aa3e992d0594519983880a29f17301923e7)) * Update dependency org.graalvm.buildtools:junit-platform-native to v0.9.28 ([#2692](https://togithub.com/googleapis/java-spanner/issues/2692)) ([d8a2b02](https://togithub.com/googleapis/java-spanner/commit/d8a2b02d43a68e04bebb2349af61cc8901ccd667)) * Update dependency org.graalvm.buildtools:native-maven-plugin to v0.9.28 ([#2705](https://togithub.com/googleapis/java-spanner/issues/2705)) ([2b17f09](https://togithub.com/googleapis/java-spanner/commit/2b17f095a294defa5ea022c243fa750486b7d496)) * Update dependency org.junit.vintage:junit-vintage-engine to v5.10.1 ([#2723](https://togithub.com/googleapis/java-spanner/issues/2723)) ([9cf6d0e](https://togithub.com/googleapis/java-spanner/commit/9cf6d0eae5d2a86c89de2d252d0f4a4dab0b54a4)) --- This PR was generated with [Release Please](https://togithub.com/googleapis/release-please). See [documentation](https://togithub.com/googleapis/release-please#release-please).
For fixing - #2659
Base Refactoring Done
lastUseTimeparameter fromPooledSessiontoSessionImplclass.FakeClockearlier was only being used withinSessionPoolclass. Now it has to be used with multiple classes sincelastUseTimewas moved toSessionImplclass. Now moved it to a new class due to multiple usages.New Changes Made
TransactionRunnerImplandAbstractReadContextclass.DatabaseClientImplTestthat now ensures thatlastUseTimenow gets updated with every RPC. Previously these tests were failing.