Command Pattern via TCP

I’m trying with ETS tables. There’s something I don’t get.. I create the table in the Command module, as soon as it’s loaded:

  @on_load :init
  def init() do
    res = :ets.new(:commands, [
      :named_table,
      :ordered_set,
      :public,
      {:read_concurrency, true},
      {:write_concurrency, true}
    ])
    whereis = :ets.whereis(:commands)
    content = :ets.tab2list(:commands)
    Logger.debug("table created: #{inspect(res)} #{inspect(whereis)} #{inspect(content)}")
  end

This works fine:

21:45:58.988 [debug] table created: :commands #Reference<0.2865878229.9043973.175739> []

The __using__ macro is like this now, with a Process.sleep to make sure the ETS table is setup at that point:

defmacro __using__(opts) do
    quote do
      @behaviour Command

      @on_load :register_command

      def register_command() do
        Process.sleep(5000)
        Command.register_command(__MODULE__, unquote(opts))
      end

      def parse_args(_cmd_args), do: {:ok, nil}
      defoverridable [parse_args: 1]
    end
  end

And then in the register_command, I try to insert:

  def register_command(module, cmd_opts) do
    Logger.debug("register_command: #{module} #{inspect(cmd_opts)}")
    cmd_name = Keyword.fetch!(cmd_opts, :name)
    :ets.insert(:commands, {cmd_name, module})
  end

But this, after the 5 seconds, crashes:

21:53:54.865 [warn]  The on_load function for module Elixir.Commands.Info returned:
{:badarg,
 [
   {:ets, :insert, [:commands, {"info", Commands.Info}],
    [error_info: %{cause: :id, module: :erl_stdlib_errors}]},
   {Command, :register_command, 2, [file: 'lib/command.ex', line: 60]},
   {:code_server, :"-handle_on_load/5-fun-0-", 1,
    [file: 'code_server.erl', ...]}
 ]}

21:53:54.858 [error] Process #PID<0.211.0> raised an exception
** (ArgumentError) errors were found at the given arguments:

  * 1st argument: the table identifier does not refer to an existing ETS table

    (stdlib 3.15.2) :ets.insert(:commands, {"info", Commands.Info})
    lib/command.ex:60: Command.register_command/2
    (kernel 8.0.2) code_server.erl:1317: anonymous fn/1 in :code_server.handle_on_load/5

How does the table name, :commands, not refer to an existing ETS table? I don’t get. Is this because it’s happening at compile time and when the compilation finishes, the ETS table dies?