Open zobar opened 1 year ago
On closer examination, this ticket is not related to #1751. I've confirmed that the default AsyncExecutorProvider
has poor performance compared to the synchronous API, but by providing a larger thread pool, it is possible to achieve better performance than the synchronous API.
@arpan14 Can you please help triage this issue.
I believe the workaround is to use AsyncTransactionManager
directly. That appears to actually be asynchronous (i.e. not just doing blocking calls in the executor).
I'm surprised that AsyncRunner
wraps the blocking TransactionManager
rather than wrapping AsyncTransactionManager
.
AsyncRunner.runAsync
performs a blocking get inside its executor. This may result in deadlock if the following conditions are met:This is most likely to manifest itself if the application has a constrained global thread pool optimized for running non-blocking operations. In particular, we noticed this in a Cats Effect application, although the bug is not restricted to Scala or Cats Effect.
This may also be causing the performance problems noted in #1751.Our workaround is to provide a dedicated thread pool that is only used for
runAsync
, but which is not used by the work itself.I've built a minimum test case in Java to demonstrate this issue.
Environment details
OS type and version: Mac OS Ventura 13.6 Java version: OpenJDK 21 Versions:
com.google.cloud:google-cloud-spanner:6.52.1
Steps to reproduce
Code example
External references such as API reference guides
The API documentation for
runAsync
does not mention that it runs blocking operations in the executor.