Trevoke

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

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: https://github.com/elixir-lang/elixir/blob/master/lib/logger/lib/logger.ex#L147
  • Check the result of GenServer.whereis/1 just 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 recon or redbug.
Trevoke

Trevoke

@michalmuskala @christhekeele

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

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!

Trevoke

Trevoke

Oof, this is old! (well, old-ish).

So, what was happening in my test was, it turns out, very simple: I had async behavior that existed independently of the tests. As a consequence, the test could end before the behavior could be resolved.

I think I solved this by a combination of two techniques:

  1. I decided that I did not need to do async testing and I just tested the behavior inline
  2. I decided that I could pass the test process in with self() and use assert_receive to cause a synchronous wait for a message

HTH!

christhekeele

christhekeele

I had this problem before Elixir 1.4 when I forgot to add the umbrella dependency to my list of applications in my mix.exs, but I’m not sure that would be a problem with the new extra_applications.

Where Next?

Popular in Questions Top

srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
chewm
Hi guys, nice to meet you to the whole forum, I’m new here, I’m trying to configure visual studio code for elixir, right now the intellis...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New

Other popular topics Top

srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
273 38985 115
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
magnetic
Hey :wave:t3: Elixir community, I’ve been learning Elixir, and working on some side projects. My editor of choice is VSCode, and althoug...
New

We're in Beta

About us Mission Statement