Genserver mail box size

Hello All,

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.)

Thanks!

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.

2 Likes

Because :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.

1 Like

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 Process.info/1 route.

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.

5 Likes

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

1 Like

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.