http://erlang.org/pipermail/erlang-questions/2014-November/081843.html
erts_use_sender_punish is a flag hard coded to 1 (true), when it is true
a process sending messages to another process will have its reduction
count reduced by the number of messages in the receivers message queue
multiplied by four. Sending messages to processes with zero messages in
the queue is free in terms of reductions, but sending messages to load
queues is very expensive and will lead the scheduler to context switch
to another process more often.
I.E. reductions are reduced based on the mailbox size of the receiver process.
It’s not designed to ‘save’ a system, just allow it to handle load better. If you runaway by spamming messages that the receiver can’t go through fast enough then you will still eventually run out of memory, you should use call
if that’s possible, thus causing a synchronization point, however not even call will save you if a process is being spawned (like a web request) to make that call
, you can still run out of memory that way, but backpressure will still ‘slow it down’ so it won’t happen quite as fast (and in fact in these short-lived process cases then cast
could be better as the process could die sooner, saving memory). The BEAM’s built-in backpressure works best with many sending to few processes many times.
EDIT: Also, as a side note, using call
instead of cast
is not backpressure, it is forcing a queue size of 1 instead of N between those two processes, which only helps when one process is sending a lot of messages to another, not when a lot of processes are sending a message to one (which it can hurt).
EDIT2: Oh hey, OTP 19 added a flag (max_heap_size
) to set the maximum size of the entire process, including its mailbox, before OTP will kill the process so you can set that to prevent entire VM death.
EDIT3: You know, the new :atomics
module would make it quite nice to make a wrapper to pretend the mailbox of a process is self-limitating, or perhaps pretend it’s like a bounded queue so the caller can do ‘something else’ if it is getting overloaded… This could be a good and cheap pattern for pretending that some messages are allowed to be lossy in certain situations… ^.^
EDIT4: Oh hey, @ferd has a webpage about all kinds of different backpressure patterns and ways to handle overload via a variety of different ways for a variety of different circumstances, it looks pretty comprehensive.
https://ferd.ca/handling-overload.html