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

RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
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
marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New

Other popular topics Top

joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 42716 114
New

We're in Beta

About us Mission Statement