fix(spanner): prevent memory leak and thread blocking in transaction keep-alive - #13897
fix(spanner): prevent memory leak and thread blocking in transaction keep-alive#13897olavloite wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Code Review
This pull request refactors the transaction keep-alive mechanism in ReadWriteTransaction by using a ScheduledThreadPoolExecutor with removeOnCancelPolicy enabled, and converting KeepAliveRunnable into a static nested class with a WeakReference to prevent memory leaks. It also introduces lock-based synchronization using abortedLock to avoid sending keep-alive pings when the transaction is busy. Feedback on this PR highlights a critical issue where the keep-alive loop can silently terminate when the transaction is busy; because keepAliveFuture.isDone() is still false during execution, the synchronous call to reschedule the ping results in a no-op. A fix is suggested to reset keepAliveFuture to null before rescheduling.
d5e0904 to
8c8c44d
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request refactors the keep-alive mechanism in ReadWriteTransaction to prevent memory leaks and improve task cancellation. It changes KeepAliveRunnable to a static class using a WeakReference to the transaction, replaces the scheduled executor with a ScheduledThreadPoolExecutor configured to remove cancelled tasks, and introduces a rescheduling mechanism when the transaction is busy. A critical issue was identified in the newly added test testKeepAliveRescheduledWhenLockBusy, where the use of a ReentrantLock on the same thread allows tryLock() to succeed due to reentrancy, thereby failing to test the actual rescheduling path. The lock should be acquired on a separate thread to correctly simulate a busy transaction.
8f18b7e to
8b5aaa6
Compare
…keep-alive - Enable `setRemoveOnCancelPolicy(true)` on `KEEP_ALIVE_SERVICE` so canceled tasks are immediately purged from `DelayedWorkQueue`. - Use a `WeakReference<ReadWriteTransaction>` in `KeepAliveRunnable` to prevent scheduled tasks from retaining strong references to transaction instances. - Use `abortedLock.tryLock()` in `KeepAliveRunnable` so the shared executor thread does not block when a transaction is active or retrying. - Remove duplicate `maybeScheduleKeepAlivePing` listener registration on keep-alive query completion. - Add unit tests in `ReadWriteTransactionTest` verifying task removal on cancel, weak reference retention, non-blocking lock handling, and single ping scheduling on completion.
8b5aaa6 to
ef6529f
Compare
setRemoveOnCancelPolicy(true)onKEEP_ALIVE_SERVICEso canceled tasks are immediately purged fromDelayedWorkQueue.WeakReference<ReadWriteTransaction>inKeepAliveRunnableto prevent scheduled tasks from retaining strong references to transaction instances.abortedLock.tryLock()inKeepAliveRunnableso the shared executor thread does not block when a transaction is active or retrying.maybeScheduleKeepAlivePinglistener registration on keep-alive query completion.ReadWriteTransactionTestverifying task removal on cancel, weak reference retention, non-blocking lock handling, and single ping scheduling on completion.