Dynamically spawning processes

350 views
Skip to first unread message

Roberts Guļāns

unread,
Jan 29, 2016, 2:57:22 PM1/29/16
to elixir-lang-talk
Hello, i am new to elixir, so maybe i am missing something.

How can i dynamically spawn processes?
So how can i check if named process is running, if not - start it?


Ben Wilson

unread,
Jan 29, 2016, 3:11:17 PM1/29/16
to elixir-lang-talk
Hey welcome. I definitely recommend looking through some of the books as they will cover the general patterns that exist for managing process life cycles.

The getting started guides actually go through some basic supervision examples.



In general you never manually check to see if a named process is running and then start it. Supervisors should fill that role.

Roberts Guļāns

unread,
Feb 1, 2016, 3:01:01 PM2/1/16
to elixir-lang-talk
So i have process (resources list) that creates child process each single resource. Child processes should be created only when needed and child process should be exited if, for example, 30 seconds it does not receive any message.

So parent process should be able to create child process or use already running process. If you say supervisors should be in charge of that, can you elaborate on that? can you please give some code examples, maybe in github/stackoverflow?I have red "Programming Elixir" OTP chapter and now am going over "Elixir in Action".

Saša Jurić

unread,
Feb 1, 2016, 5:18:30 PM2/1/16
to elixir-lang-talk
Some of your questions should be answered by Elixir in Action (full disclosure, I'm the author), but here's the gist of it.

To start children dynamically you need a :simple_one_for_one supervisor (for example, see here). This is basically a supervisor where children are started on-demand.

That supervisor should most likely be registered under some alias, so other clients don't need to know its pid. So when starting a supervisor, you may want to provide the :name option (e.g. here).

To start children on demand, you can use Supervisor.start_child/2. In this example it's wrapped in the function call. Notice how the registered name is used to identify the supervisor. This allows any child to invoke Todo.ServerSupervisor.start_child without knowing the pid of the supervisor.

So now all you ned to do is put such supervisor somewhere in your supervision tree. Then, any client can call Todo.ServerSupervisor.start_child to start the child.


When it comes to auto-stopping the idle server, there are two options. If it's a GenServer, then you can specify the idle timeout in the handler response. Basically, in all response tuples of GenServer callbacks (init, handle_call, handle_cast, handle_info) you can add additional argument which is millisecond time. If no message arrives to the GenServer in the given time, then you'll get handle_info(:timeout, state), and from there you can return {stop, :normal, state} to make the server stop.

The problem with this is that you need to include the timeout info in all of your callbacks. If you have a more complicated situation where some messages should reset the timer, while others should leave it, then you need to resort to Process.send_after, or :erlang.start_timer (I'd probably use the latter). With these functions a process can ask from BEAM to send it a message sometimes in the future. Then, if the process receives a normal message (not the timeout) which should reset the timer, you can cancel the future message with Process.cancel_timer, and request another future message. This is basically a lease renewal.

If you receive the requested future message, it means the process was idle and you can stop it.

Roberts Guļāns

unread,
Feb 2, 2016, 1:25:33 AM2/2/16
to elixir-lang-talk
Thanks for your reply, will try your example.
Great book by the way. 
Reply all
Reply to author
Forward
0 new messages