A Release Task to Run a Test Process

I will start by saying that this is work-related, the environment is within a space where I cannot directly copy/paste code, and I’ll do everything in my power to get as close to the actual code as I can without going over (because I have a thing for being employed). That said…

…my team is tasked with building a thing that simulates activity that occurs in production. This activity simulation will aid developers in all spaces. The concept is to allow for start of this thing through a release task that is run after the app itself is started, via “_build/dev/rel/my_app/bin/my_app rpc MyApp.ReleaseTasks.run_this_thing” (for example).

This is the bit where I try to get as close as I can with code examples.

The release task:

defmodule MyApp.ReleaseTasks do
  @moduledoc false
  require Logger

  def start_the_thing do
    Logger.info("Ensuring all started")
    {:ok, _} = Application.ensure_all_started(:my_web_service)
  
    spawn(fn ->
       Logger.info("Starting Thing")
       MyWebService.Thing.start_supervised([])
       Process.sleep(:infinity)
    end)
  end
end

Thing itself will be a little bit more difficult to abstract here, since it kind of goes into stuff I really can’t share here, but know that it is a GenServer. It has a defdelegate/2 function which delegates the above start_supervised/1 to a different module’s start_link/1, an init/1 that starts doing things, then shifts the rest to a handle_continue/2, one handle_info/2 that deals with a :rerun atom that occurs every second, and a terminate/2.

[a representation of] The “different module” from above, to which that bit of work is delegated:

defmodule MyApp.Thing.Supervisor do
  @moduledoc false
  use Supervisor

  def start_link(config) do
     Supervisor.start_link(__MODULE__, config, name: __MODULE__)
  end

  @impl true
  def init(_) do
    children = [
      {MyApp.Thing, []}
    ]

    Supervisor.init(children, strategy: :one_for_one, max_restarts: 371_292)
  end
end

All the mocking/simulating work occurs in a fourth module.

And now, the issue: I can’t tell where a failure to start occurs. I’m able to start it in iex with no issues, but when I go to run the release task command, I only see the Logger output from within the spawn/1 function, then it stops. I don’t even see the Logger output above that! I’m not sure how best to proceed further. I’ve tried logging all over, reconfiguring logs to show me as much as possible, and am still unable to get any insight as to what may be the issue. Truth be told, I’m a bit out of my depth here, so the path might even be right in front of me, but I’m not certain of it.

Have you got sasl and otp reports turned on in logger config?

https://hexdocs.pm/logger/Logger.html#module-boot-configuration

I do now. Unfortunately, the logging still ends at the one Logger statement (and still hops over the previous one).

Got no immediate help for you but have you tried replacing spawn with pid = Task.async and Task.await(pid)?

1 Like

Definitely going to throw that in the mix.

So, it turns out that it was an issue where we were using IO.puts/1 instead of Logger. Noticed that there were memory and performance issues because IO was trying to puts to nothing. Changed to Logger and, even though no logs were visible, the problem went away.

1 Like