I wonder if it’s related to [erlang-questions] “New” vs. “old” console behavior: bug or feature?
The user.erl process forwards that data to the shell. The shell
attempts to evaluate it, and if there’s not enough data, it asks for
more. user.erl then blocks until it can get more data to respond to the
io request.
It sounds like the user process can get stuck in a selective receive - so if it’s responsible for anything else that would be blocked too.
REPL? A bit more (and less) than that
PS: Though it sounds like the behaviour of the old shell - not the current one with user_drv
(though according to observer user
is running).
Seems the first shell’s group leader is getting stuck here as soon as you try to connect back to it.
iex(1)> spid = self()
#PID<0.84.0>
iex(2)> {:group_leader, leader_1} = Process.info spid, :group_leader
{:group_leader, #PID<0.53.0>}
iex(3)> {:group_leader, leader} = Process.info leader_1, :group_leader
{:group_leader, #PID<0.35.0>}
iex(4)> {:group_leader, ^leader} = Process.info leader, :group_leader
{:group_leader, #PID<0.35.0>}
iex(5)> defmodule Foo do
...(5)> def loop do
...(5)> IO.puts "Looping..."
...(5)> :timer.sleep(1000)
...(5)> loop()
...(5)> end
...(5)> end
{:module, Foo,
<<70, 79, 82, 49, 0, 0, 4, 8, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 108, 0,
0, 0, 12, 10, 69, 108, 105, 120, 105, 114, 46, 70, 111, 111, 8, 95, 95, 105,
110, 102, 111, 95, 95, 9, 102, 117, ...>>, {:loop, 0}}
iex(6)> Foo.loop()
Looping...
Looping...
Looping...
Looping...
Looping...
User switch command
--> s 'Elixir.IEx'
--> c 2
Interactive Elixir (1.5.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> leader_1 = pid("0.53.0")
#PID<0.53.0>
iex(2)> Process.info leader_1, :message_queue_len
{:message_queue_len, 0}
iex(3)> Process.info leader_1, :messages
{:messages, []}
iex(4)> Process.info leader_1, :current_location
{:current_location, {:group, :server_loop, 3, [file: 'group.erl', line: 113]}}
iex(5)>
User switch command
--> c 1
User switch command
--> c 2
nil
iex(6)> Process.info leader_1, :message_queue_len
{:message_queue_len, 2}
iex(7)> Process.info leader_1, :messages
{:messages, [{#PID<0.51.0>, {:data, '\r'}}, {#PID<0.51.0>, {:data, '\r'}}]}
iex(8)> Process.info leader_1, :current_location
{:current_location, {:group, :server_loop, 3, [file: 'group.erl', line: 113]}}
iex(9)> Process.whereis :user_drv
#PID<0.51.0>
iex(10)>
Variation on the theme:
iex(1)> leader_1 = Process.group_leader()
#PID<0.53.0>
iex(2)> {:group_leader, leader} = Process.info leader_1, :group_leader
{:group_leader, #PID<0.35.0>}
iex(3)> {:group_leader, ^leader} = Process.info leader_1, :group_leader
{:group_leader, #PID<0.35.0>}
iex(4)> defmodule Foo do
...(4)>
...(4)> def start(),
...(4)> do: (Kernel.spawn_link &loop/0)
...(4)>
...(4)> def loop do
...(4)> IO.puts "Looping..."
...(4)> :timer.sleep(1000)
...(4)> loop()
...(4)> end
...(4)> end
{:module, Foo,
<<70, 79, 82, 49, 0, 0, 4, 228, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 141,
0, 0, 0, 15, 10, 69, 108, 105, 120, 105, 114, 46, 70, 111, 111, 8, 95, 95,
105, 110, 102, 111, 95, 95, 9, 102, 117, ...>>, {:loop, 0}}
iex(5)>
nil
iex(6)> Foo.start()
Looping...
#PID<0.127.0>
Looping...
Looping...
Looping...
Looping...
Looping...
Looping...
iex(7)>
User switch command
--> s 'Elixir.IEx'
--> c 2
Interactive Elixir (1.5.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> leader_1 = pid("0.53.0")
#PID<0.53.0>
iex(2)> Process.info leader_1, :message_queue_len
{:message_queue_len, 0}
iex(3)> Process.info leader_1, :messages
{:messages, []}
iex(4)> Process.info leader_1, :current_location
{:current_location, {:group, :more_data, 5, [file: 'group.erl', line: 638]}}
iex(5)>
User switch command
--> c 1
nil
iex(8)> Process.info leader_1, :message_queue_len
{:message_queue_len, 0}
iex(9)> Process.info leader_1, :messages
{:messages, []}
iex(10)> Process.info leader_1, :current_location
{:current_location, {:group, :server_loop, 3, [file: 'group.erl', line: 113]}}
iex(11)> foo_pid = pid("0.127.0")
#PID<0.127.0>
iex(12)> Process.info foo_pid, :group_leader
{:group_leader, #PID<0.53.0>}
iex(13)> Process.info foo_pid, :current_location
{:current_location, {:io, :execute_request, 2, [file: 'io.erl', line: 572]}}
iex(14)>
Basically the spawned process is stuck here presumably waiting for a response from the group_leader which never comes. Looks like the response to the IO request got lost because the group_leader is waiting for more data.