elixir-ecto / myxql

MySQL 5.5+ driver for Elixir
Apache License 2.0
273 stars 67 forks source link

timeout: :infinity ignored? #128

Closed wmnnd closed 4 years ago

wmnnd commented 4 years ago

Hey there,

I’m using myxql (0.4.3) with ecto_sql (3.5.3).

I was trying to run a query within a migration using Repo.query!/3. The operation kept timing out after 15 seconds even though I had specified timeout: :infinity in the Repo.query!/3 opts.

So I tried wrapping the Migration in my own transaction, again using timeout: :infinity:

MyRepo.transaction(fn -> Ecto.Migrator.run(MyRepo, :up, all: true) end, timeout: :infinity)

Still, the transaction would time out after 15 seconds giving the following error:

** (DBConnection.ConnectionError) socket closed (the connection was closed by the pool, possibly due to a timeout or because the pool has been terminated)
    lib/ecto/adapters/sql.ex:751: Ecto.Adapters.SQL.raise_sql_call_error/1
    lib/ecto/migration/runner.ex:336: Ecto.Migration.Runner.log_and_execute_ddl/3
    lib/ecto/migration/runner.ex:117: anonymous fn/6 in Ecto.Migration.Runner.flush/0
    (elixir 1.11.2) lib/enum.ex:2181: Enum."-reduce/3-lists^foldl/2-0-"/3
    lib/ecto/migration/runner.ex:116: Ecto.Migration.Runner.flush/0
    (stdlib 3.13.2) timer.erl:166: :timer.tc/1
    lib/ecto/migration/runner.ex:25: Ecto.Migration.Runner.run/8
    lib/ecto/migrator.ex:349: Ecto.Migrator.attempt/8

Next I tried manually running just my Repo.query!/3 call outside of a transaction/migration and it did not time out. But since I needed the migration to run, this was no help.

My last attempt to make this work was to simply try a numerical value instead of :infinity: MyRepo.transaction(fn -> Ecto.Migrator.run(MyRepo, :up, all: true) end, timeout: :100_000) Lo and behold, this worked like a charm and finished after just about 80 seconds.

Could this be a bug in myxql or does this sound like an issue with Ecto or ecto_sql?

wojtekmach commented 4 years ago

Thank you for the report, I wasn't able to reproduce it, it seems fine on both ecto & myxql side of things. An easy way to trigger the timeout is SELECT sleep(20) (sleep for 20s) and the option is taken into consideration:

iex> Repo.query!("SELECT SLEEP(20)", [], timeout: 1111)
20:58:22.854 [error] MyXQL.Connection (#PID<0.370.0>) disconnected: ** (DBConnection.ConnectionError) client #PID<0.357.0> timed out because it queued and checked out the connection for longer than 1111ms

if you could prepare a sample app that you can reproduce the issue, I'll be happy to take a look further.

wmnnd commented 4 years ago

I created a sample app using select sleep as you suggested but I was unable to reproduce the issue using the exact same versions of myxql and Ecto as in my original setup. So I’ll go ahead and close the issue, maybe if someone else comes across this problem they can reopen it :smiley: