Combine spill strategies#16069
Conversation
It's not needed since memory revocation is called on every reservation.
db394f4 to
ce2f3fc
Compare
pettyjamesm
left a comment
There was a problem hiding this comment.
Looks good to me modulo a few minor comments added inline. I can't think of a better option to avoid concurrent memory pool and query revoking other than the single threaded executor approach taken here, which should be ok as long as expensive operations don't somehow migrate into the caller thread (potential risk: OperatorContext#memoryRevocationRequestListener and associated ListenableFuture<?> callbacks on Driver#driverBlockedFuture registered in Driver#initialize()).
There was a problem hiding this comment.
Why not newSingleThreadExecutor(threadsNamed("memory-revocation"))? Seems like this is serving to enable the .getCorePoolCount() check in the primary constructor, but seems acceptable to omit the assertion if the executor creation is hard coded (maybe just move the comment to the creation site?).
The added benefit is that single threaded executors are wrapped in a FinalizableDelegatedExecutorService which will call shutdown if the executor is leaked without being shutdown first (a likely scenario in tests that might fail to call stop()).
There was a problem hiding this comment.
Yeah, it was entirely to be able to get the corePoolCount. I'll change it.
There was a problem hiding this comment.
Now that this instance is created in the constructor, it should be shutdown in the stop() method to avoid leaking it.
There was a problem hiding this comment.
It wasn't created in the constructor for the tests, but I'll actually just change the tests to get the executor from here, and that will remove any need to do any checking about the pool size.
00db8b0 to
e436416
Compare
|
@pettyjamesm comments addressed and all tests passing |
There was a problem hiding this comment.
Clever, I didn't realize that invokeAll() blocked until completion like this.
There was a problem hiding this comment.
Missing MemoryRevokingScheduler#stop() which would now leak the single threaded executor until GC finalization. Minor, but worth avoiding. Maybe a withMemoryRevokingScheduler(<params>, Consumer<MemoryRevokingScheduler>) helper could help with the boiler-plate of registerPoolListeners() and stop() but would be a problem with the way that InterruptedException is thrown from awaitAsynchronousCallbacksRun()...
Open to your thoughts about the best way to resolve the tension between test sanity and ensuring the revoking executor remains single threaded even with future refactoring changes.
There was a problem hiding this comment.
ended up going with a simple try/finally pattern in the tests to start and stop the memory revoking scheduler
Always have memory-pool spilling running whenever per-query spilling is enabled to prevent a situation, where the memory pool could fill up without spill being triggered. This is a problem because the OOM killer won't kick in if there is any revocable memory allocated. The problem exists for the PER_TASK_MEMORY_THRESHOLD spill strategy as well, but we don't address it here as the fix is more complicated, and we expect to remove that strategy in the future.
TestJdbcClient.testAlterColumns failed in a ci run. See prestodb#16081.
d475e99 to
06aebfd
Compare
Test plan - unit tests