コンテナ内で動くスケジューラが一定時間で動かなくなるバグを追っていた。最初はスケジューラが止まってしまうのかと予想していたが、ブロックしてずっと待っていただけだった。 スレッドダンプをとったらわかった。
"scala-execution-context-global-1802" - Thread t@1802 java.lang.Thread.State: WAITING at sun.misc.Unsafe.park(Native Method) - parking to wait for <15b7d45> (a java.util.concurrent.SynchronousQueue$TransferStack) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:458) at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362) at java.util.concurrent.SynchronousQueue.take(SynchronousQueue.java:924) at com.google.common.util.concurrent.Uninterruptibles.takeUninterruptibly(Uninterruptibles.java:233) at com.google.cloud.spanner.SessionPool$Waiter.take(SessionPool.java:411) at com.google.cloud.spanner.SessionPool$Waiter.access$3300(SessionPool.java:399) at com.google.cloud.spanner.SessionPool.getReadSession(SessionPool.java:754) at com.google.cloud.spanner.DatabaseClientImpl.readOnlyTransaction(DatabaseClientImpl.java:62) at jp.co.cyberss.live.common.core.client.SpannerClient.withinReadOnly(SpannerClient.scala:42) (略)
結論としてはtransactionをクローズしてなかっただけだった。。。
SpannerのSessionは枯渇した場合にデフォルトでブロックする。
SpannerのAPIにはSingleUseとそうでないものがあり、前者は AutoClosingReadContext を継承しているので自動でcloseしてくれる。そうでないものは明示的にcloseを呼ばないといけない。
なおこの時点でのSpannerのAPIのバージョンは 0.25.0-beta
(https://github.com/GoogleCloudPlatform/google-cloud-java/tree/v0.25.0/google-cloud-spanner/src/main/java/com/google/cloud/spanner)を使っていた。