-
Notifications
You must be signed in to change notification settings - Fork 123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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.
google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionImpl.java
Show resolved
Hide resolved
@@ -73,6 +73,8 @@ abstract static class Builder<B extends Builder<?, T>, T extends AbstractReadCon | |||
private QueryOptions defaultQueryOptions = SpannerOptions.Builder.DEFAULT_QUERY_OPTIONS; | |||
private ExecutorProvider executorProvider; | |||
|
|||
private Clock clock; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually meant setting this one (so Builder.clock
) by default to = new Clock()
. That way, the clock in the AbstractReadContext
can be final.
@@ -416,6 +425,7 @@ void initTransaction() { | |||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using this.clock = firstNonNull(builder.clock, this.clock);
google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionImpl.java
Outdated
Show resolved
Hide resolved
google-cloud-spanner/src/main/java/com/google/cloud/spanner/SessionPool.java
Outdated
Show resolved
Hide resolved
google-cloud-spanner/src/main/java/com/google/cloud/spanner/AbstractReadContext.java
Show resolved
Hide resolved
google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java
Outdated
Show resolved
Hide resolved
Options.priority(RpcPriority.HIGH))) { | ||
while (resultSet.next()) {} | ||
} | ||
poolMaintainerClock.currentTimeMillis += Duration.ofMillis(2050).toMillis(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the detailed explanation, that sounds good to me.
google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java
Outdated
Show resolved
Hide resolved
google-cloud-spanner/src/test/java/com/google/cloud/spanner/DatabaseClientImplTest.java
Outdated
Show resolved
Hide resolved
} | ||
|
||
@Override | ||
public void prepareReadWriteTransaction() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably for a different PR, but this seems like a left-over from before InlineBeginTransaction.
…redundant updates from SessionPool class.
… more unit tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, with a minor nit on the Builder classes for AbstractReadContext and TransactionContext
@@ -73,6 +73,8 @@ abstract static class Builder<B extends Builder<?, T>, T extends AbstractReadCon | |||
private QueryOptions defaultQueryOptions = SpannerOptions.Builder.DEFAULT_QUERY_OPTIONS; | |||
private ExecutorProvider executorProvider; | |||
|
|||
private Clock clock; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually meant setting this one (so Builder.clock
) by default to = new Clock()
. That way, the clock in the AbstractReadContext
can be final.
@@ -392,6 +399,8 @@ void initTransaction() { | |||
private final int defaultPrefetchChunks; | |||
private final QueryOptions defaultQueryOptions; | |||
|
|||
private Clock clock = new Clock(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above, I think this can be made final
google-cloud-spanner/src/main/java/com/google/cloud/spanner/TransactionRunnerImpl.java
Outdated
Show resolved
Hide resolved
google-cloud-spanner/src/main/java/com/google/cloud/spanner/TransactionRunnerImpl.java
Outdated
Show resolved
Hide resolved
google-cloud-spanner/src/main/java/com/google/cloud/spanner/TransactionRunnerImpl.java
Outdated
Show resolved
Hide resolved
Options.priority(RpcPriority.HIGH))) { | ||
while (resultSet.next()) {} | ||
} | ||
poolMaintainerClock.currentTimeMillis += Duration.ofMillis(2050).toMillis(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the detailed explanation, that sounds good to me.
…ansactionRunnerImpl.java Co-authored-by: Knut Olav Løite <koloite@gmail.com>
…ansactionRunnerImpl.java Co-authored-by: Knut Olav Løite <koloite@gmail.com>
…ansactionRunnerImpl.java Co-authored-by: Knut Olav Løite <koloite@gmail.com>
🤖 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
lastUseTime
parameter fromPooledSession
toSessionImpl
class.FakeClock
earlier was only being used withinSessionPool
class. Now it has to be used with multiple classes sincelastUseTime
was moved toSessionImpl
class. Now moved it to a new class due to multiple usages.New Changes Made
TransactionRunnerImpl
andAbstractReadContext
class.DatabaseClientImplTest
that now ensures thatlastUseTime
now gets updated with every RPC. Previously these tests were failing.