Absinthe subscriptions broken?

I’m trying to use subscriptions in Absinthe, but keep getting this error when I try to start the server:

** (Mix) Could not start application pb: exited in: Pb.Application.start(:normal, [])
    ** (EXIT) an exception was raised:
        ** (FunctionClauseError) no function clause matching in Absinthe.Subscription.child_spec/1
            (absinthe) lib/absinthe/subscription.ex:43: Absinthe.Subscription.child_spec(PbWeb.Endpoint)
            (elixir) lib/supervisor.ex:624: Supervisor.init_child/1
            (elixir) lib/enum.ex:1336: Enum."-map/2-lists^map/1-0-"/2
            (elixir) lib/enum.ex:1336: Enum."-map/2-lists^map/1-0-"/2
            (elixir) lib/supervisor.ex:615: Supervisor.init/2
            (elixir) lib/supervisor.ex:564: Supervisor.start_link/2
            (kernel) application_master.erl:277: :application_master.start_it_old/4

This is in a completely vanilla app, freshly created using:

mix phx.new pb --no-html
cd pb
mix ecto.create

Then following the directions here: https://github.com/absinthe-graphql/absinthe/blob/master/guides/subscriptions.md

I’m following the directions for 1.4.x

And then doing
iex -S mix phx.server

Does anyone know why it breaks for me?

:wave:

Can you post your lib/application.ex here? Judging by the error alone, there is a problem at https://github.com/absinthe-graphql/absinthe/blob/v1.4/lib/absinthe/subscription.ex#L43 so it’d be helpful to see how you define the children for the supervisor.

According to the guide for version 1.4 it should be like this:

[
  # other children ...
  supervisor(MyAppWeb.Endpoint, []), # this line should already exist
  supervisor(Absinthe.Subscription, [MyAppWeb.Endpoint]), # add this line
  # other children ...
]

On the master branch they’ve added the child_spec approach but note that the guide doesn’t include it. I’d try something like

[
      # Start the Ecto repository
      MyAppWeb.Repo,
      # Start the endpoint when the application starts
      MyAppWeb.Endpoint,
      {Absinthe.Subscription, [MyAppWeb.Endpoint]} # <-- note this is different from the guide
    ]

since in v1.4 child_spec expects a list, not a single module atom.

2 Likes

Actually, the supervisor(...) calls are for 1.3 from what I understand, because in 1.4 the direct call to supervisor() has been supplanted by doing Supervisor.start_link(...).

So on the page I linked above (from absinthe-graphql’s github repo), it says to add it like so:
{Absinthe.Subscription, PbWeb.Endpoint} to the children list. Doing this results in the problem I reported above.

However, doing what you suggest fixes the issue! So in case this may help others, here is what the relevant part of my application.ex looks like:

    # List all child processes to be supervised
    children = [
      # Start the Ecto repository
      Pb.Repo,
      # Start the endpoint when the application starts
      PbWeb.Endpoint,
      # Starts a worker by calling: Pb.Worker.start_link(arg)
      # {Pb.Worker, arg},
      {Absinthe.Subscription, [PbWeb.Endpoint]}
    ]

    # See https://hexdocs.pm/elixir/Supervisor.html
    # for other strategies and supported options
    opts = [strategy: :one_for_one, name: Pb.Supervisor]
    Supervisor.start_link(children, opts)
  end

Thank you very much, idiot!

1 Like