Closed jonleighton closed 3 years ago
Hi @jonleighton, how is it going? :D
Yes, this can happen in cases like above because, if you crash while using the connection, then we don't know what is the state in a connection? Did you receive part of the select? Are you in a transaction? Etc. Therefore all we can do is abort.
The scenario you described for wallaby can definitely happen and likely what is happening. Cowboy will send an exit signal to the request process if the connection terminates. You can however stop this by calling Process.flag(:trap_exit, true)
. I would recommend adding a plug that runs only in test to your endpoint that:
Process.flag(:trap_exit, true)
That should fix intermittent reproductions. I assume you are using the Plug SQL Sandbox? Perhaps we should make it easy to add so there.
Can you try this commit and let me know how it goes? https://github.com/phoenixframework/phoenix_ecto/commit/1d8d28a82eef1ff496851bd2fd53661398d38b99
Hi @josevalim! I am enjoying being an Elixir programmer these days so thank you :grin:
And thanks for pushing that fix to phoenix_ecto
, I'm convinced you must be some kind of hyper advanced AI bot with that sort of response time :rofl:
In the the real world app that I encountered this problem we have tweaked our flakey test to avoid the problem, and it was also quite rare to get a repro anyway. But I have updated the test app I made to:
phoenix_ecto
master to get your fixIt works a charm :slightly_smiling_face: I did have to increase :queue_interval
due to the slightly contrived conditions of the test.
So I think we can close this, high fives all around :clap:
If I have two processes:
DBConnection.Ownership.ownership_checkout/2
DBConnection.Ownership.ownership_allow/4
B runs a long-running query, or otherwise makes use of the connection.
For some reason or other, B is then killed. We see a log message like this:
DBConnection
disconnected the database connection, even though the process that exited didn't own the connection.Now Process A is no longer able to use its connection, even though it owns it.
This seems like surprising behaviour to me, but maybe I'm missing something? Maybe it's not possible to prevent this scenario?
I have written a test that demonstrates this problem. It is in the context of a Phoenix/Ecto app, and uses
Ecto.Adapters.SQL.Sandbox
, but theDBConnection.Ownership
calls above are what is happening under the hood.When I run that test I see the following:
Some additional context
I experienced this problem in the real world via a flakey test that does full-stack browser testing via Wallaby. The test runs with
async: true
, and the database connection owned by the test process is shared with the web endpoint via Phoenix.Ecto.SQL.Sandbox.Here's roughly what I think was happening when the test failed: