Using Process.sleep for rate limiting external requests?

It’s basically the same thing except that Process.sleep also handles :infinity,
dunno if it’s a common pattern or not.

Your current method will block your GenServer from handling system messages under the hood: your GenServer code is just a part of it.

You probably want a GenServer state with a queue of some sorts (could be a simple list for lifo processing if you don’t care about the order in which they arrive versus are being handled) in combination with a wait flag.

If wait is true, simply prepend the incoming request to the list of pending requests (or use a :queue). If wait is false and queue is empty, process the request by calling dispatch_request/1. If queue is non-empty, queue the request and start processing the queue.

dispatch_request/1 should return either:

  • {:ok, response} or
  • {:wait, milliseconds} if it sees a 429 response.

In the first case, if queue is non-empty, you process the next entry.
In the latter case, you queue the (failed) request, set wait to true and use Process.send_after/4 to send yourself a :resume message at a later point in time.

Something like that anyway.

1 Like