This will be a quick one, since I didn’t really upgrade to Phoenix v1.2.0, unfortunately… Why, why not?!
The main reason I was eager to upgrade was the new Presence feature. It will really streamline my code, and allow me to easily implement the monitoring stuff I mentioned in the previous post. Also, my tests are getting slow, so having the ecto async goodness would be great as well.
The reason I didn’t upgrade is because I’ve tried to, and it didn’t work out.
First off, after the upgrade, I ran my tests, and got a whole lot of long error stacktraces on my console. I’ve included a few at the bottom. The first one I tackled was the FunctionClauseError
related to the handle_info
stuff. After spending about an hour at the Elixir slack channel, turns out it was a bug in the db_connection
library.
That’s not too bad, but seeing that this is just one error, and I now see at least three more different ones, I just can’t spend the time to dig into each and every one!
It probably makes sense at this point not to upgrade a sufficiently complex application, and wait for the release to stabilize. I have a new project in Elixir, tho, and it’s using v1.2.0 without issues. This is because I can easily avoid troublesome patterns in the new app, but it would take forever to migrate the old app.
Just a quick example of a “troublesome” pattern, that is spinning off GenServers and processes that interact with the DB. Apparently, the new Ecto sandbox stuff is nice and all, but quite restrictive. To properly use it, you either have to do it right from the get-go, or refactor your whole implementation.
That’s about it! Here are some relevant logs:
This is the log of the issue related to this pr:
03:18:08.674 [error] GenServer #PID<0.346.0> terminating
** (FunctionClauseError) no function clause matching in Socks.UserState.handle_info/2
(socks) web/state/user_state.ex:16: Socks.UserState.handle_info({#Reference<>, {:ok, {#PID<>, #Reference<>}, Ecto.Adapters.SQL.Sandbox.Connection, {Postgrex.Protocol, %Postgrex.Protocol{}, false}}}, %{user: %Socks.User{}})
(stdlib) gen_server.erl:615: :gen_server.try_dispatch/4
(stdlib) gen_server.erl:681: :gen_server.handle_msg/5
(stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
This one is a completely random DBConnection error that doesn’t make any sense to me. I’m not sure about it, so I can’t really open an issue on Github…
Update: One of the Ecto developers told me it’s a bug already fixed on master.
03:46:11.179 [error] Postgrex.Protocol (#PID<0.218.0>) disconnected: ** (DBConnection.ConnectionError) client #PID<0.270.0> exited: an exception was raised:
** (FunctionClauseError) no function clause matching in Ecto.Adapters.SQL.Sandbox.Pool.disconnect/4
(ecto) lib/ecto/adapters/sql/sandbox.ex:371: Ecto.Adapters.SQL.Sandbox.Pool.disconnect({#PID<0.210.0>, #PID<0.218.0>, {#PID<0.218.0>, #Reference<0.0.4.38>}}, %DBConnection.ConnectionError{message: "owner #PID<0.269.0> exited while client #PID<0.272.0> is still running with: shutdown"}, {Postgrex.Protocol, %Postgrex.Protocol{buffer: "", connection_id: 20156, null: nil, parameters: #Reference<0.0.1.1465>, postgres: :transaction, queries: 163889, sock: {:gen_tcp, #Port<0.7617>}, timeout: 15000, transactions: :naive, types: 139307}, false}, [timeout: :infinity, repo: Socks.Repo, sandbox_pool: DBConnection.Poolboy, ownership_pool: Ecto.Adapters.SQL.Sandbox.Pool, pool_timeout: 5000, adapter: Ecto.Adapters.Postgres, username: "xxx", password: "xxx", database: "xxx", hostname: "xxx", pool: DBConnection.Ownership])
(db_connection) lib/db_connection/ownership/proxy.ex:234: DBConnection.Ownership.Proxy.down/2
(stdlib) gen_server.erl:615: :gen_server.try_dispatch/4
(stdlib) gen_server.erl:681: :gen_server.handle_msg/5
(stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
Finally, many people have been running into this, but it seems the only way to avoid it is to properly manage your access to the DB and make sure all transactions are complete within the test time frame?
04:40:47.009 [error] GenServer #PID<0.274.0> terminating
** (stop) exited in: GenServer.call(#PID<0.267.0>, {:checkout, #Reference<0.0.2.2087>, true, 15000}, 5000)
** (EXIT) shutdown: "owner #PID<0.266.0> exited with: shutdown"
(db_connection) lib/db_connection/ownership/proxy.ex:32: DBConnection.Ownership.Proxy.checkout/2
(db_connection) lib/db_connection.ex:716: DBConnection.checkout/2
(db_connection) lib/db_connection.ex:623: DBConnection.run/3
(db_connection) lib/db_connection.ex:464: DBConnection.prepare_execute/4
(ecto) lib/ecto/adapters/sql.ex:228: Ecto.Adapters.SQL.sql_call/6
(ecto) lib/ecto/adapters/sql.ex:400: Ecto.Adapters.SQL.execute_and_cache/7
(ecto) lib/ecto/repo/queryable.ex:127: Ecto.Repo.Queryable.execute/5
(ecto) lib/ecto/repo/queryable.ex:40: Ecto.Repo.Queryable.all/4
(ecto) lib/ecto/repo/queryable.ex:72: Ecto.Repo.Queryable.one!/4
(socks) web/state/user_state.ex:20: Socks.UserState.handle_info/2
(stdlib) gen_server.erl:615: :gen_server.try_dispatch/4
(stdlib) gen_server.erl:681: :gen_server.handle_msg/5
(stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3