1

I'm new to elixir, experimenting around in iex shell to learn, and I have be a noob question.

For simplicity let's call the current shell session process the "main process".

I spawn a child process, write a receive block in "main process" to listen for child message. When hit enter, it'll put the "main process" into a waiting status. This basically freezes the "main process", making it irresponsive to further input.

Many times I got stuck in this status by mistake. If I mess up I need to shutdown the shell and start over again, losing all the states and setups.

My question: is there a way to withdraw/invalidate/break out of a working receive block?

Or maybe is there a way that I can start another session, without killing the previous one, then send some message to it to unfreeze it?

hackape
  • 18,643
  • 2
  • 29
  • 57

2 Answers2

2

Taking the second approach will require a bit of work. Each iex instance is a separate OTP node, so in order to make those two talk to each other, you'll need to do the following:

  1. specify the same cookie and a different name for each of them:
iex --cookie foo --name "node1@127.0.0.1"
iex --cookie foo --name "node2@127.0.0.1"
  1. associate a global name with the receiver node (run in node1):
:global.register_name(:node1, self())
  1. connect node1 to node2 (run in node1):
Node.connect(:"node2@127.0.0.1")

Now, you can start listening for messages in node1 with receive. To send a message from node2 to node1, find out its PID within the cluster and dispatch the message there:

:global.whereis_name(:node1) |> send "Hello!"
Vadim Landa
  • 2,784
  • 5
  • 23
  • 33
  • I like this approach! I know that I can put a `.iex.exs` file in the cwd, but it cannot handle CLI options. Is there a way to save options in a config file? – hackape Apr 09 '21 at 13:11
1

I don't think you can interrupt receive, you could kill the process using its PID from another process or set a timeout to it, then you get back the control of the session if nothing was received between this timeout window.

receive do
  a -> a
after
  1_000 -> "nothing after 1s"
end

take a look at https://elixir-lang.org/getting-started/processes.html#send-and-receive

Evaldo Bratti
  • 7,078
  • 2
  • 18
  • 19
  • "kill the process using its PID" you mean to kill the "main procss"? That's precisely what I want to avoid. – hackape Apr 09 '21 at 11:43
  • But yeah, put in `after` kinda solve my problem, good idea. Just need to remember doing it everytime. Still hope to see other answer, if no I'll accept this one. – hackape Apr 09 '21 at 11:45