Being rather new to the Azure Durable Functions landscape, I am struggling to find the best way to handle downstream calls to an API that has rate limits implemented.
The way my flow is set up, is like below:
- HistorySynchronizer_HttpStart function: has
HttpTrigger
andDurableClient
bindings in the signature and calls the next orchestration function: - HistorySynchronizer function: has
OrchestrationTrigger
binding in the signature. This function will make a call to the API (await) and get a collection back. For every item in that collection, it will start a new Activity:context.CallActivityAsync()
(combining them in aList
and perform aTask.WhenAll()
) - ProcessActivity functions: has
ActivityTrigger
binding in the signature. This function will have to make a call to the rate-limited API endpoint. And it's these activities I want to throttle (across multiple orchestrations).
So, what I am looking for is an implementation to a throttling pattern:
- I need a shared state that is thread-safe (I was thinking about Durable Entity) that keeps track of the number of calls made to that API
- Before the ProcessActivity function makes the call to that API, it has to check with the Durable Entity if it can call the API, or if it has to wait a certain TimeSpan before performing that call.
- In case it has to wait, the Activity would have to 'sleep', and I was thinking about a Durable Timer, but it seems that should be used in an Orchestration function, instead of an Activity function.
- In case the call to the API is allowed, the Activity has to update the Rate counter in that shared state object.
I don't see a standard implementation to achieve this and I want to move as much of that Check/Sleep logic away from the main orchestration.
Would the best approach be to have a suborchestration implemented for every API call that has to be throttled, where the check has to happen, before the Activity is called?
Looking forward to any insights.