Skip to content

Commit

Permalink
feat: ExMachina.start/2: return a supervisor from Application callback (
Browse files Browse the repository at this point in the history
#434)

We're actually returning the PID for an Agent rather than a
supervisor.  In addition to being against the erlang callback spec:

    The function is to return {ok,Pid} or {ok,Pid,State}, where Pid
    is the pid of the top supervisor and State is any term. If
    omitted, State defaults to []. If the application is stopped
    later, State is passed to Module:prep_stop/1.

Some tools like phoenix live dashboard will send the application
supervisor supervisor-y messages and end up crashing the root
application tree.

    ** (FunctionClauseError) no function clause matching in Agent.Server.handle_call/3
        (elixir 1.14.5) lib/agent/server.ex:11: Agent.Server.handle_call(:which_children, {#PID<0.22073.22>, #Reference<0.3953567925.3593732098.137638>}, %{})
        (stdlib 3.17) gen_server.erl:721: :gen_server.try_handle_call/4
        (stdlib 3.17) gen_server.erl:750: :gen_server.handle_msg/6
        (stdlib 3.17) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
    Last message (from #PID<0.22073.22>): :which_children

This change makes ExMachina return a supervisor with a single child -
the ExMachina.Sequence.  Have also moved to `use Agent` to get the
child_spec/1 for free in ExMachina.Sequence.

This has been tested per the tool versions file (1.7.4 + otp 21).
  • Loading branch information
aeruder authored and doomspork committed Jan 18, 2024
1 parent e8edf47 commit c9ebb47
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 2 deletions.
7 changes: 6 additions & 1 deletion lib/ex_machina.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ defmodule ExMachina do
@callback build_pair(factory_name :: atom, attrs :: keyword | map) :: list

@doc false
def start(_type, _args), do: ExMachina.Sequence.start_link()
def start(_type, _args) do
Supervisor.start_link([ExMachina.Sequence],
strategy: :one_for_one,
name: __MODULE__.Supervisor
)
end

defmacro __using__(_opts) do
quote do
Expand Down
4 changes: 3 additions & 1 deletion lib/ex_machina/sequence.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ defmodule ExMachina.Sequence do
sequential values instead of calling this module directly.
"""

use Agent

@doc false
def start_link do
def start_link(_) do
Agent.start_link(fn -> Map.new() end, name: __MODULE__)
end

Expand Down

0 comments on commit c9ebb47

Please sign in to comment.