Исправлено «владелец #PID <…> выход с: shutdown» в тестах для моего метода завершения / 2 в Phoenix.Channel - PullRequest
0 голосов
/ 23 октября 2019

Требуется помощь в тестировании завершение / 2 обратного вызова в моем канале.

Проверка и настройка выглядит следующим образом:

setup do
  :ok = Ecto.Adapters.SQL.Sandbox.checkout(MyApp.Repo)
  Ecto.Adapters.SQL.Sandbox.mode(MyApp.Repo, {:shared, self()})

  {:ok, socket} = connect(UserSocket, %{token: "some_token"})
  {:ok, %{}, socket} = subscribe_and_join(socket, "some_channel", %{})

  %{socket: socket}
end

test "terminate/2", %{socket: socket} do
  # for avoiding "** (EXIT from #PID<...>) {:shutdown, :closed}"
  Process.unlink(socket.channel_pid)

  assert close(socket) == :ok
  # some additional asserts go here
end

В методе прекращения / 2Я просто вызываю вспомогательный модуль, назовем его TerminationHandler.

def terminate(_reason, _socket) do
  TerminationHandler.call()
end

И метод call / 0 в TerminationHandler содержит запрос к БД. Это может выглядеть примерно так:

def call() do
  users = User |> where([u], u.type == "super") |> Repo.all # line where error appears
  # some extra logic goes here
end

Это ошибка, которую я получаю периодически (может быть, один раз в 10 запусков)

14:31:29.312 [error] GenServer #PID<0.1041.0> terminating
** (stop) exited in: GenServer.call(#PID<0.1040.0>, {:checkout, #Reference<0.3713952378.42205187.247763>, true, 60000}, 5000)
    ** (EXIT) shutdown: "owner #PID<0.1039.0> exited with: shutdown"
    (db_connection) lib/db_connection/ownership/proxy.ex:32: DBConnection.Ownership.Proxy.checkout/2
    (db_connection) lib/db_connection.ex:928: DBConnection.checkout/2
    (db_connection) lib/db_connection.ex:750: DBConnection.run/3
    (db_connection) lib/db_connection.ex:644: DBConnection.execute/4
    (ecto) lib/ecto/adapters/postgres/connection.ex:98: Ecto.Adapters.Postgres.Connection.execute/4
    (ecto) lib/ecto/adapters/sql.ex:256: Ecto.Adapters.SQL.sql_call/6
    (ecto) lib/ecto/adapters/sql.ex:436: Ecto.Adapters.SQL.execute_or_reset/7
    (ecto) lib/ecto/repo/queryable.ex:133: Ecto.Repo.Queryable.execute/5
    (ecto) lib/ecto/repo/queryable.ex:37: Ecto.Repo.Queryable.all/4
    (my_app) lib/my_app/helpers/termination_handler.ex:4: MyApp.Helpers.TerminationHandler.call/0
    (stdlib) gen_server.erl:673: :gen_server.try_terminate/3
    (stdlib) gen_server.erl:858: :gen_server.terminate/10
    (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Last message: {:join, Phoenix.Channel.Server}Last message: {:join, Phoenix.Channel.Server}

Буду признателен за любые ответы, касающиеся причин этой ошибки и возможныхспособы избежать этого.

1 Ответ

0 голосов
/ 23 октября 2019

Как указано в документации для GenServer.terminate/2:

[...], руководитель отправит сигнал выхода :shutdown и GenServer будет иметь продолжительность тайм-аута для завершения. Если по истечении этого времени процесс все еще жив, он будет немедленно убит.

Это, по-видимому, ваш случай. DBConnection.checkout/2, кажется, ожидает появления доступного соединения, и это продолжается по истечении времени ожидания. Следовательно, владелец подвергается жестокому убийству.

Возможны два возможных решения:

  • увеличить время ожидания отключения (я бы этого не допустил)
  • увеличить количестворазрешенных одновременных подключений к базе данных.

Последнее, вероятно, необходимо в любом случае, так как ваш пул кажется заполненным. Таким образом, соединение будет немедленно проверено, и оно должно успешно вернуться через интервал ожидания.

...