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
Cancel running command when a (pooled) connection is closed #1801
Comments
If it's expensive would it be better to cancel the running command when getting a connection? |
@YohDeadfall it's going to cost the same whether it happens on close or on open... In other words, it's merely a question of which thread is going to pay the price - the one closing or the one opening. If we do this, I think it's quite important to do this on close rather than on open - after a connection is returned to the pool, it may spend quite a bit of time there before it's reallocated again. We don't want the command to keep running while the connection is idle in the pool (it may be eating resources at the server etc...). But there's another way to look at this - when closing a pooled connection with a running command, Npgsql could asynchronously perform the cancellation. In other words, it would release the closing thread immediately and execute the cancellation without blocking anyone. This would remove any serious perf hit - connections would simply take a bit longer to become available again as idle in the pool, but opening and closing threads would not be (directly) affected. If we go down this route, it seems important to make sure cancellation completed fully before actually marking the connection as idle and putting it into the pool. We don't want any non-idle connections to get in there. Implementation-wise, this logic should probably happen as part of |
I have some questions about this:
|
@mdalepiane the standard way to cancel a command in PG is described here - this isn't with @vonzshik you may be interested in this given all the cancellation work you've been doing recently. |
A few points: |
@vonzshik you're right about the breaking change, it's a good question. I did feel at the time that closing a connection implies cancelling a running command - and I still think that makes sense to some extent. But I agree that it's probably not worth the breaking change to people. However, one thought in this area is that the waiting for the query to complete can be done asynchronously and "out of band". In other words, Close can be made 100% synchronous (for pooled connections), without waiting for any sort of cleanup, but rather firing it off in parallel. Once the cleanup is complete and the resultset is consumed, the connection is returned to the pool - but there's no reason for use code to wait on that (in Close). Of course, it could be claimed that this is also a small breaking change, in case user code expects that when Close completes the query has finished. That doesn't sound like a very strong argument to me. But I'm not sure this is a very valuable optimization - and users can implement it themselves as well if that's what they want. What do you think @vonzshik? |
I do agree, it kind of makes sense. But that's not something I'm comfortable to break without a good reason (and right now we don't have one).
There is still one problem - the using var reader = cmd.ExecuteReader();
// some code, which doesn't read the response completely
connection.Close(); And I'm not really sure it's really worth adding a cancellation on |
Yeah, I agree there's not much reason to do anything here. I'll close this, but if anyone wants to provide another perspective please post here and we'll reconsider. |
Spawned from #1800. When closing a pooled connection, check if a command is currently running and cancel if so.
Keep in mind that cancellation is a very expensive operation (opening a new TCP socket to the server) and should only happen if necessary.
The text was updated successfully, but these errors were encountered: