Help upgrading phoenix socket client lib to phoenix 1.4

Hi guys!

I’m trying to upgrade the current library for phoenix socket client for elixir itself https://github.com/Aircloak/phoenix_gen_socket_client, which is more than a year old and works for 1.3, but has several outdated things, like Poison dependency, cowboy, among others, and i can’t fix the tests.

It creates a generic base phoenix app, but fails to launch the endpoint:

     ** (EXIT from #PID<0.265.0>) shutdown: failed to start child: Phoenix.PubSub.PG2
         ** (EXIT) shutdown: failed to start child: Phoenix.PubSub.LocalSupervisor
             ** (EXIT) an exception was raised:
                 ** (ArgumentError) argument error
                     (stdlib) :ets.new(TestSite.Endpoint, [:set, :named_table, {:read_concurrency, true}])
                     (phoenix_pubsub) lib/phoenix/pubsub/local_supervisor.ex:24: Phoenix.PubSub.LocalSupervisor.init/1
                     (stdlib) supervisor.erl:295: :supervisor.init/1
                     (stdlib) gen_server.erl:374: :gen_server.init_it/2
                     (stdlib) gen_server.erl:342: :gen_server.init_it/6
                     (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3

The weird thing is that i run on iex :ets.new(TestSite.Endpoint, [:set, :named_table, {:read_concurrency, true}]) and runs ok

this is the declaration of the testSite:

defmodule TestSite do
  @moduledoc false

  defmodule PubSub do
    @moduledoc false
    def start_link(), do: Registry.start_link(keys: :duplicate, name: TestSite.PubSub)

    def subscribe(subscriber_key), do: Registry.register(__MODULE__, subscriber_key, nil)

    def notify(subscriber_key, message) do
      __MODULE__
      |> Registry.lookup(subscriber_key)
      |> Enum.map(fn {pid, _value} -> pid end)
      |> Enum.each(&send(&1, message))
    end
  end

  defmodule Endpoint do
    @moduledoc false
    use Phoenix.Endpoint, otp_app: :phoenix_gen_socket_client

    socket("/test_socket", TestSite.Socket, websocket: true, longpoll: false)
    socket("/test_socket_updated", TestSite.SocketUpdated, websocket: true, longpoll: false)

    @doc false
    def init(:supervisor, config) do
      {:ok,
       Keyword.merge(
         config,
         https: false,
         http: [port: 29_876],
         secret_key_base: String.duplicate("abcdefgh", 8),
         debug_errors: false,
         server: true,
         pubsub: [adapter: Phoenix.PubSub.PG2, name: __MODULE__]
       )}
    end
  end
...

any clues?

This probably means the endpoint is already started, or that there is at least an :ets table with that name already:

iex(1)> :ets.new(TestSite.Endpoint, [:set, :named_table, {:read_concurrency, true}])
TestSite.Endpoint
iex(2)> :ets.new(TestSite.Endpoint, [:set, :named_table, {:read_concurrency, true}])
** (ArgumentError) argument error
    (stdlib) :ets.new(TestSite.Endpoint, [:set, :named_table, {:read_concurrency, true}])

Maybe that helps point you in the right direction?

1 Like

I checked ets tables right before start, and there’s no table with that name:

the endpoint:

  defmodule Endpoint do
    @moduledoc false
    use Phoenix.Endpoint, otp_app: :phoenix_gen_socket_client

    socket("/test_socket", TestSite.Socket, websocket: true, longpoll: false)
    socket("/test_socket_updated", TestSite.SocketUpdated, websocket: true, longpoll: false)

    @doc false
    def init(:supervisor, config) do
      IO.inspect(:ets.all |> Enum.filter(fn x -> is_atom(x) end))
      {:ok,
       Keyword.merge(
         config,
         https: false,
         http: [port: 29_876],
         secret_key_base: String.duplicate("abcdefgh", 8),
         debug_errors: false,
         server: true,
         pubsub: [adapter: Phoenix.PubSub.PG2, name: __MODULE__]
       )}
    end
  end

the test results:

phoenix_gen_socket_client % mix test
Compiling 1 file (.ex)
[:telemetry_handler_table, :ssl_pem_cache, :httpc_manager__session_db,
 :httpc_manager__handler_db, :hex_version, :httpc_hex__session_db,
 :httpc_hex__handler_db, TestSite.PubSub, ExUnit.OnExitHandler, :logger,
 :ac_tab, :inet_db, :inet_cache, :inet_hosts_byname, :inet_hosts_byaddr,
 :inet_hosts_file_byname, :inet_hosts_file_byaddr, :global_locks, :global_names,
 :global_names_ext, :global_pid_names, :global_pid_ids, :file_io_servers,
 :elixir_config, :elixir_modules, Plug.Keys, Plug.Upload, :ranch_server,
 :cowboy_clock]


  0) Phoenix.Channels.GenSocketClientTest: failure on setup_all callback, all tests have been invalidated
     ** (EXIT from #PID<0.265.0>) shutdown: failed to start child: Phoenix.PubSub.PG2
         ** (EXIT) shutdown: failed to start child: Phoenix.PubSub.LocalSupervisor
             ** (EXIT) an exception was raised:
                 ** (ArgumentError) argument error
                     (stdlib) :ets.new(TestSite.Endpoint, [:set, :named_table, {:read_concurrency, true}])
                     (phoenix_pubsub) lib/phoenix/pubsub/local_supervisor.ex:24: Phoenix.PubSub.LocalSupervisor.init/1
                     (stdlib) supervisor.erl:295: :supervisor.init/1
                     (stdlib) gen_server.erl:374: :gen_server.init_it/2
                     (stdlib) gen_server.erl:342: :gen_server.init_it/6
                     (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3

If i remove the init() it doesn’t start at all.
Would be that Endpoint.start_link() isn’t the right way to start the endpoint without a supervisor anymore?

any other hint?

Ah so for one thing, in a test, use start_supervised(Endpoint). This will ensure that the endpoint is shut down in the given test case before it is started in another test case. Can you show where you’re calling start_link right now?

same thing with start_supervised(Endpoint)

This is where it’s being called at Phoenix.Channels.GenSocketClientTest

  setup_all do
    ExUnit.CaptureLog.capture_log(fn -> Endpoint.start_link() end)
    #start_supervised(Endpoint)
    :ok
  end

this is the repo and the test file that i’m working on right now
https://github.com/naaano/phoenix_gen_socket_client/blob/jason/test/socket_client_test.exs