-
Notifications
You must be signed in to change notification settings - Fork 124
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
Conversation
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.
@@ -580,9 +581,9 @@ public static CloseableExecutorProvider createAsyncExecutorProvider( | |||
return FixedCloseableExecutorProvider.create(executor); | |||
} | |||
|
|||
private SpannerOptions(Builder builder) { | |||
protected SpannerOptions(Builder builder) { |
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.
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) { |
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.
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 { |
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.
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() { |
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.
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); |
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.
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.
…googleapis/java-spanner into virtual-threads-internal-option
@@ -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(); |
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.
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.
Adds support for using virtual threads in the Connection API. Virtual
threads can be enabled for two things:
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.