AndrewKlymchuk

AndrewKlymchuk

Sandbox shared mode doesn't work for Task.async_stream/3

Hello,
I’ve encountered a problem when using Task.async_stream/3 within tests where sandbox shared mode is enabled.

I have the following test:

defmodule MyApp.SharedModeTest do
  use MyApp.DataCase, async: false

  test "shared mode works" do
      MyApp.Repo.transaction(fn ->
        Task.async_stream(
          [1],
          fn id -> MyApp.Repo.get(MySchema, id) end,
          timeout: :infinity
        )
        |> Enum.to_list()
      end)
  end
end

DataCase content looks as follow:

  setup tags do
    :ok = Sandbox.checkout(MyApp.Repo)

    unless tags[:async] do
      Sandbox.mode(MyApp.Repo, {:shared, self()})
    end

    :ok
  end

It fails with the following exception:

** (EXIT from #PID<0.3878.0>) exited in: DBConnection.Holder.checkout(#PID<0.3879.0>, [log: #Function<13.86356856/1 in Ecto.Adapters.SQL.with_log/3>, source: "my_table", cast_params: [1], repo: MyApp.Repo, timeout: 15000, pool_size: 10, pool: DBConnection.Ownership, ownership_timeout: 600000, queue_target: 600000, queue_interval: 600000])
         ** (EXIT) shutdown: %DBConnection.ConnectionError{message: "client #PID<0.3878.0> timed out because it queued and checked out the connection for longer than 15000ms\n\nClient #PID<0.3878.0> is still using a connection from owner at location:\n\n    (elixir 1.17.1) lib/task/supervised.ex:292: Task.Supervised.stream_reduce/7\n    (elixir 1.17.1) lib/enum.ex:4423: Enum.reverse/1\n    (elixir 1.17.1) lib/enum.ex:3748: Enum.to_list/1\n    (ecto_sql 3.11.3) lib/ecto/adapters/sql.ex:1358: anonymous fn/3 in Ecto.Adapters.SQL.checkout_or_transaction/4\n    (db_connection 2.6.0) lib/db_connection.ex:1710: DBConnection.run_transaction/4\n    ...

Apparently, db connection isn’t shared with task process, therefore it tries to check it out, but fails because it is already checked out by test process.
If I remove transaction from the test, it works as expected:

defmodule MyApp.SharedModeTest do
  use MyApp.DataCase, async: false

  test "shared mode works" do
      Task.async_stream(
        [1],
        fn id -> MyApp.Repo.get(MySchema, id) end,
        timeout: :infinity
      )
      |> Enum.to_list()
  end
end

My perception is that transaction must not affect db connection sharing among processes.
Is it a bug, or I misunderstand how it must work?

Where Next?

Popular in Questions Top

JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
dokuzbir
Hello, I am trying to convert my lists to string without losing brackets.For start i have 3 map. They look like these buyer = %{ id: ...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
Fl4m3Ph03n1x
Background Let’s assume I have a typical GenServer that receives messages as requests, does some operation in a DB and returns responses....
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs &amp; Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3268 119930 1237
New
shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
977 41022 311
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
mgjohns61585
Could someone help me? I'm making my first elixir program, number guessing game. I can't figure out how to convert the user's guess from ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New

We're in Beta

About us Mission Statement