I am working on two Elixir applications that interact via HTTP API calls.
The first application is bigger and for debugging/manual testing purposes I sometimes need to pilot HTTP responses of the second one. I created a controller in app2 that, after receiving a request, stops with an
IO.gets call and asks the user for what response to return. This works like a charm if app2 is started without a
iex session (
mix run --no-halt) but when started with
iex -S mix the user input is not received.
After some search on the web, I understand that the io of a given process is handled by its group leader and that there can be only one process handling standard input. In the
iex scenario the process handling stdin is the shell itself but the group leader of my controller is another process so the input is never received by the controller. (All correct?)
My current solution (simplified) is the following:
defmodule InteractiveController do def handle_request(req) do fix_group_leader() resp = IO.gets("Select response\n") resp end defp fix_group_leader, do: :user_drv |> Process.whereis() |> set_group_leader() # we are in a iex session, we should get shell group leader and set it for current process defp set_group_leader(pid) when is_pid(pid) do iex_group_leader = pid |> Process.info() |> get_in([:dictionary, :current_group]) Process.group_leader(self(), iex_group_leader) end # no iex session defp set_group_leader(_), do: :ok end
This works but it seems a bit hacky…
Is there a better way to find the shell group leader?
Changing the group leader for the controller has some side effect?