Skip to content
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

chore: add support for virtual threads to Connection API #2789

Merged
merged 10 commits into from
Jan 29, 2024

Conversation

olavloite
Copy link
Collaborator

Adds support for using virtual threads in the Connection API. Virtual
threads can be enabled for two things:

  1. As the StatementExecutor thread for each connection.
  2. As the gRPC transport thread pool.

Both options can (for now) only be set in the Connection API.

Setting any of these options only has any effect if the application is
running on Java 21 or higher.

Adds support for using virtual threads in the Connection API. Virtual
threads can be enabled for two things:
1. As the StatementExecutor thread for each connection.
2. As the gRPC transport thread pool.

Both options can (for now) only be set in the Connection API.

Setting any of these options only has any effect if the application is
running on Java 21 or higher.
@olavloite olavloite requested a review from a team as a code owner January 19, 2024 15:00
@product-auto-label product-auto-label bot added size: l Pull request size is large. api: spanner Issues related to the googleapis/java-spanner API. labels Jan 19, 2024
@@ -580,9 +581,9 @@ public static CloseableExecutorProvider createAsyncExecutorProvider(
return FixedCloseableExecutorProvider.create(executor);
}

private SpannerOptions(Builder builder) {
protected SpannerOptions(Builder builder) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This allows us to create a subclass specifically for the Connection API, and make the protected properties available there as well, which again allows us to make some options only available to the Connection API.

* has any effect on Java 21 and higher. In all other cases, the option will be ignored.
*/
@BetaApi
protected Builder setUseVirtualThreads(boolean useVirtualThreads) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By keeping this method protected here, it is not possible to set this from outside the package. We can then add a sub class to the Connection API and use it there.

this.interceptors = Collections.unmodifiableList(interceptors);
}

void shutdown() {
executor.shutdown();
}

void awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method was not used anywhere, so removing it.

/**
* Shutdown this executor now and do not wait for any statement that is being executed to finish.
*/
List<Runnable> shutdownNow() {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Return value is not used anywhere, so changing to void

@@ -294,6 +294,9 @@ public void stressTest() throws Exception {
() -> {
while (!stopMaintenance.get()) {
runMaintenanceLoop(clock, pool, 1);
// Sleep 1ms between maintenance loops to prevent the long-running session remover
// from stealing all sessions before they can be used.
Uninterruptibles.sleepUninterruptibly(1L, TimeUnit.MILLISECONDS);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unrelated to this change, but the existing implementation would often get into an eternal loop on my laptop, as the maintenance worker would be so quick that it would remove all sessions from the pool due to them being 'long-running', that the threads that tried to check out sessions never got a chance to finish.

@@ -80,6 +81,7 @@ class ReadWriteTransaction extends AbstractMultiUseTransaction {
private static final String MAX_INTERNAL_RETRIES_EXCEEDED =
"Internal transaction retry maximum exceeded";
private static final int MAX_INTERNAL_RETRIES = 50;
private final ReentrantLock abortedLock = new ReentrantLock();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is changed to use a ReentrantLock instead of a synchronized block, because Java virtual threads cannot be unmounted when they are inside a synchronized block.

@olavloite olavloite requested a review from ankiaga January 25, 2024 12:39
@olavloite olavloite added the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Jan 25, 2024
@yoshi-kokoro yoshi-kokoro removed the kokoro:force-run Add this label to force Kokoro to re-run the tests. label Jan 25, 2024
@olavloite olavloite added the automerge Merge the pull request once unit tests and other checks pass. label Jan 29, 2024
@gcf-merge-on-green gcf-merge-on-green bot merged commit c99189c into main Jan 29, 2024
25 of 26 checks passed
@gcf-merge-on-green gcf-merge-on-green bot deleted the virtual-threads-internal-option branch January 29, 2024 11:20
@gcf-merge-on-green gcf-merge-on-green bot removed the automerge Merge the pull request once unit tests and other checks pass. label Jan 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api: spanner Issues related to the googleapis/java-spanner API. size: l Pull request size is large.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants