Erlang receive message -- how is it done internally? - erlang

How is the receive message implemented internally in erlang runtime?
When the process is waiting for a message, the execution hang on the receive.
The receive is done via blocking IO, or asynchronous IO ?
If former, then it means the OS thread is blocked and if there are many process hang on receiving, the performance is bad in reason of thread context switch and also may reach the operation system's thread limitation.

Erlang processes are not corresponded to OS threads or processes. They are implemented as internal structures of Erlang VM and they are scheduled by Erlang VM. The number of OS threads which are started by Erlang VM by default is equal to CPU number. When the Erlang process is waiting for a message no one OS process or thread is blocked.

Related

Erlang IO blocking native calls best practices

I've done a lot of reading lately about calling my C code from Erlang. My C code will be making a remote call and I expect to have a timeout of ~10 seconds. In order to keep Erlang responsive and handle additional requests while someone else is waiting for the initial call to C, what are the best practices in 2022?
We can use async port drivers or a NIF with ERL_NIF_DIRTY_JOB_IO_BOUND to run it on the dirty IO scheduler.
My understanding is that the async port driver would be the best option, but looking for more insight here.
Let's say we have an Erlang web server handling two callers A and B. A makes a call which then enters into C and blocks for 10 seconds. While that is waiting, B makes their call which will also need to call C. With an async port driver and a dirty IO NIF what are the differences in execution and blocking? Will B get blocked in Erlang, waiting for the port driver or NIF to be ready to start working on this new request (if that's a thing), or waiting for an available thread (as I understand the async port driver will use its own single thread (unless I do something else to spawn another thread)? And the NIF would use a threadpool).
If we have even more callers calling in where will we bottleneck?
As you can see I have quite a few questions and would highly appreciate help from those with Erlang familiarity!

Busy Wait Avoidance

The operating system can avoid busy wait of a process by putting it to sleep and restoring it in case of an event. For restoring the operating system needs to check on the event occurance, it means the operating system or some part of it is struck in busy wait ?
Is it possible to have a interrupt driven I/O in software context?
Only Between I/O and process not between processes.
For restoring the operating system needs to check on the event occurance, it means the operating system or some part of it is struck in busy wait?
No.
Is it possible to have a interrupt driven I/O in software context?
Yes.
Only Between I/O and process not between processes.
Yes.
Computers haven't used busy-wait for I/O since about 1957.

opensips-1.6: recv queue full

I am using opensips-1.6 on CentOS-5.8.
In certain conditions I am seeing lot of packets queued in recv queue and not getting processed.
I am monitoring the same using "netstat" command.
While observing the siptrace I found, opensips couldn't reply to incoming msgs, and if replied, it replies very late.
What sort of params I should observe/optimize to handle this kinda situation(when getting very high traffic on switch) ??
thnx
Possible reasons for slow UDP/TCP queue processing:
your OpenSIPS processes are in a deadlock (CPU usage 100% ?)
not enough memory! Watch the logfile for any memory-related error!
opensipsctl fifo get_statistics shmem: => to monitor shared memory usage
opensipsctl fifo get_statistics tm: => to see how many transactions are building up
not enough processes! consider increasing the number of children
To conclude, OpenSIPS 1.6 is old (from 2006) and unsupported anymore. Some of the above MI commands might not even work. You should consider upgrading to 1.11. It is stable, has lots of great features and it's LTS.

erl_nif_thread and erlang process communication

Can we communicate with erl_nif thread created and normal erlang process? We can send messages from nif thread to erlang process using nif_send but can nif thread receive messages from any erlang process like normal erlang process do?
No, a thread created with enif_thread_create is not an Erlang process and cannot receive messages.
You are probably trying to achieve too much with your NIF and might consider writing a linked in driver instead, which can send messages and receive messages from Erlang.
Alternatively, you could use a conditional variable and/or a pipe in your native thread to wait for an event which would be generated by a NIF function called from the emulator whenever the message you are expecting is received. Indeed, unlike linked in drivers, you cannot use the select interface from the emulator.

Erlang e Thrift

I want to make a Windows Service using Erlang and Thrift.
The service will have a single thread listening in a port (socket communication) and send request to a worker's thread. The Windows Service have to response quickily (milisencods) and the throughput is mandatory. (requests per second)
The workers thread will communicate each other. I think in Earlang to resolve this issue.
So i think erlang+thrift will work good. Am I right? Any suggestions?
Your solution is reasonable. To bring you up to speed i would suggest reading up on gen_server, supervisor, application.
Thrift will generate stub files which by compiling will yield you a transport/acceptor. It's up to you to provide both the thrift api and the handler for this api.
Moreover be advised not to synchronize alot between processes if you need fast response times (ie. dont design your solution around synchronizing calls)

Resources