I have a client API used to send messages to a Genserver. I want to drop messages (have the client API return
:dropped for instance) if the mailbox of the Genserver has more than a certain amount of messages.
After research, it seems like the best way to do this is to call
Process.info on the Genserver’s
pid and drop messages based on
:message_queue_len. Is this the best way to do this? I decided to not use
:sys.get_status since it seems to send a message to the Genserver which will be processed only AFTER all prior messages are processed (thus not getting the real time value of the messages in a Genserver’s mailbox.)
Hi there, Why don’t you maintain it in the GenServer state, rather than accessing it directly from the GenServer? What purpose are you trying to solve? Just trying to understand the usecase.
I would suggest doing neither. Instead immediately pull any messages into an internal queue (
ets works well here) and drop if the queue grows too large.
However, what is the motivation for this ?
GenServer mailbox can grow unbounded limited only by memory. Generally we do not worry about the mailbox and the extra complication is unnecessary.
:sys.get_state to get the state of a genserver sends a message to a genserver. So if you have 100 messages in the mailbox, each with 100ms processing time, it will be 10s before you can get the state of a genserver. I need to know how many messages there are in the mailbox before I send a message to the genserver.
I did consider that approach and I think it makes sense as a long term fix. For now, I want to avoid repeatedly sending a message to the genserver to poll an ETS table, so I wanted to go down the
The motivation is to implement a basic form of load shedding user requests. It is better to deny a user request and tell them that the system is overloaded rather than have them wait 10s for a response.
@apr if you haven’t read it I’d highly recommend reading this article: https://ferd.ca/handling-overload.html
I think it will help you inform your design.
Also worth noting that the docs for
Process.info/1 explicitly says not to use it for anything but debugging.
Process.info/2 has no warning though
Thanks for the pointer! I have read it before, but I need to revisit it in a bit to build something more robust. For the time being, I think I can only go with the naive way.
Good point! I need to just feed the items I need into
Process.info/2 which is much better than getting everything back.