Trevoke
(EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
I have an umbrella app.
Some of the apps inside depend on other apps in the umbrella, unsurprisingly.
I’m writing a test for one of the apps which currently relies on starting a process using one of the other apps.
Almost all such processes across these apps use an app-specific or purpose-specific Registry.
This is the error I get:
23:04:13.529 [error] GenServer {Registry.Mobs, 1} terminating
** (stop) exited in: GenServer.call({:via, Registry, {World.LocationRegistry, "2"}}, {:mobs, #Function<1.42779424/1 in Mobs.Bird.handle_cast/2>}, 5000)
** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
(elixir) lib/gen_server.ex:729: GenServer.call/3
(mobs) lib/mobs/bird.ex:79: Mobs.Bird.handle_cast/2
(stdlib) gen_server.erl:601: :gen_server.try_dispatch/4
(stdlib) gen_server.erl:667: :gen_server.handle_msg/5
(stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
Last message: {:"$gen_cast", :try_to_mate}
State: %Mobs.Bird{controller: #PID<0.395.0>, gender: :female, id: 1, lifespan: 39, location_id: "2", name: "a bird", pregnant: nil}
My test_helper.exs is trying to provide support to the mix.exs file which requires the apps by doing this:
Application.ensure_all_started(:world)
Application.ensure_all_started(:mobs)
Application.ensure_all_started(:controllers)
Application.ensure_all_started(:life)
ExUnit.start()
The World.Application module looks like this:
defmodule World.Application do
# See http://elixir-lang.org/docs/stable/elixir/Application.html
# for more information on OTP Applications
@moduledoc false
use Application
def start(_type, _args) do
import Supervisor.Spec, warn: false
# Define workers and child supervisors to be supervised
children = [
supervisor(Registry, [:unique, World.LocationRegistry], id: :location_registry),
supervisor(Registry, [:unique, World.PathwayRegistry], id: :pathway_registry),
supervisor(World, [%{spawn_locations: Application.get_env(:world, :spawn_locations)}])
]
# See http://elixir-lang.org/docs/stable/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one, name: World.Supervisor]
Supervisor.start_link(children, opts)
end
end
This is the test as it stands:
defmodule Mobs.BirdTest do
use ExUnit.Case
doctest Mobs.Bird
test "only mates with birds" do
import IEx
{:ok, foo} = World.Location.start_link(
%World.Location{
id: "2",
name: "center of the universe",
description: "what's on the tin",
pathways: []}
)
female_bird = Mobs.Spawn.birth(
%{module: Mobs.Bird, location_id: "2", gender: :female})
male_dwarf = Mobs.Spawn.birth(
%{module: Mobs.Dwarf, location_id: "2", gender: :male})
:ok = Mobs.Bird.try_to_mate(female_bird)
end
end
The obviously relevant code from Mobs.Bird is :
defmodule Mobs.Bird do
def try_to_mate(id) do
GenServer.cast(via_mob(id), :try_to_mate)
end
def handle_cast(:try_to_mate, state) do
looking_for = case state.gender do
:male -> :female
:female -> :male
end
possible_partners =
World.Location.mobs(
state.location_id,
fn({{module, id}, info}) -> module == __MODULE__ && info.gender == looking_for end)
if Enum.any? possible_partners do
partner = Enum.random possible_partners
case [state.gender, elem(partner, 1).gender] do
[:male, :female] -> __MODULE__.pregnantize(elem(partner, 0))
[:female, :male] -> __MODULE__.pregnantize(state.id)
end
end
{:noreply, state}
end
end
Similarly, the obviously relevant code from World.Location is :
defmodule World.Location do
def mobs(loc_id)do
mobs(loc_id, fn(_x) -> true end)
end
def mobs(loc_id, filter) do
GenServer.call(via_tuple(loc_id), {:mobs, filter})
end
def handle_call({:mobs, filter}, _from, state) do
mobs = Enum.filter(state.entities, filter)
{:reply, mobs, state}
end
end
Most Liked
michalmuskala
In order to debug this, I would try replicating the situation in a regular shell (no need to deal with timeouts, that get nasty trying to use visual tools, like observer). Some things you can then try (some are possible when running through tests as well):
- turn on sasl reports to get supervisor progress reports as described in: elixir/lib/logger/lib/logger.ex at main · elixir-lang/elixir · GitHub
- Check the result of
GenServer.whereis/1just before calling the process - Check the state of the registry ets table in observer - you should see what processes are exactly registered
- Subscribe to the events of the problematic process with
:sys.trace/2 - bring out the big guns and start tracing what is happening using
reconorredbug.
Trevoke
I found the root cause.
It turns out the way the test is written, the test ends too quickly, and since it’s an async call, the location IS ALREADY DEAD by the time I am trying to send it a message.
Fun times.
Thank you both for your time and effort here, and @michalmuskala thanks for showing me all those really cool tools, they’ve really taught me a lot.
jnmandal
FWIW, I ended up on this page because I had converted my app that I generated with mix new to have a supervisor and I had forgot to add
mod: {MyApp.Application, []}
into the mixfile’s application function. So.. if you are new and you see this error. Maybe check that!
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









