Type of calls allowed inside Erlang Process (sync/async, blocking/nonblocking)

I have the following queries on the type of calls supported in Erlang. Please clarify.

  • Akka advices to avoid Blocking calls in the actors. Is there any similar advice/restriction in Erlang?
  • Java supports Async APIs to overcome the limitation set on the number of threads per JVM. Since users are allowed to create many Erlang Processes, I understand that Async APIs are NOT needed in Erlang. Please confirm.
  • If there is any material on Erlang best practices, patterns or anti-pattern, please point me to them.

Reference:

2 Likes

There is no such thing as “call” from one process to another in Erlang. Unless you’re talking of gen_server:call flow, which is a sequence of monitor + sending a message + waiting for reply/timeout/monitor.

You can make any number of “asynchronous calls” (often referred as “multicall”) by sending “request” messages and collecting replies.

4 Likes

There’s no such restriction, there are no functions in Erlang which will block the OS thread. Call any function you like!

That’s correct, you can create millions of processes and don’t need to use specific functions in them.

2 Likes

Thanks Max. Yes, the Erlang processes communicate through messages. I am referring to calls made by a Process to perform IO or network operations (Socket, ssh, sftp, Netconf, etc)

1 Like

Thanks Louis. What about Erlang functions that perform IO or Network operations?

1 Like

Oh, so you are talking about function calls, not calls as a mode of inter-process communication. In that case, they will block unless they are done in a separate process.

3 Likes

That is, they will block the process doing the operation, not a scheduler or something else deeper in ERTS :wink: Like, in the same way as calling timer:sleep(1000) will “block” the calling process until the function call returns.

4 Likes

Yup, as @Maria-12648430 says none of it will block the scheduler or OS threads and can safely be used at any time, including functions that perform IO.

The only exception I can think of is some of the functions in the persistent_term module which will trigger global garbage collection run. (Garbage collection is normally per-process and does not involve a global pause).

2 Likes

Thanks Maria & Louis for clarifying that making blocking calls inside a Process blocks only the process, not the scheduler or the OS threads.

1 Like

May I request someone to clarify the following query?

If there is any material on Erlang best practices, patterns or anti-pattern, please point me to them.

1 Like

I’m a big fan of this book, though it’s a bit advanced. There might be some better foundational reading.

4 Likes

These operations exist in both blocking and non-blocking variants. Example with the socket API:

case socket:send(Socket, Data) of
  {ok, RestData} ->
    %% RestData is what has not been sent, but we haven't been blocked

You may want to choose blocking call, e.g. socket:send/3, that has a timeout. Calling process will be suspended for up to that amount of time. However this will not block the OS thread (unlike in Java).

It’s not an anti-pattern in Erlang to do a blocking call. In fact this allows to simplify programming model.

2 Likes