Throttling RFC #71
Replies: 7 comments 2 replies
-
Looks good! Top of mind that would cover our use-cases at the moment 🙌 I prefer:
Over:
Because:
Example 1 An example of an option - that isn't needed right away but would be a very neat "nice to have" - would be the ability to set a limit for consecutive failed executions for a group. Say I run out of credits at X API, our database or an external API is down, or whatever endpoint we ask during function execution responds with something we didn't expect... Under the assumption that I'm just gonna "set and forget" background jobs with Defer, and thus fill up a group with +10.000 requests, it would make a lot of sense for me to not waste GB seconds or API credits on executions that are gonna fail anyway. I assume history/information like this could live at the function level too but I'd use it to make sure that a) we don't spend resources on failed executions related to APIs that are "pay per request", and b) to avoid having to rerun thousands of jobs, which is currently a click-by-click kind of effort in the Defer console? Forcing me to keep a backup job queue too. I imagine something like:
Which at Example 2 Another option that would be needed for some APIs is a way to specify the rate limiting strategy. The RFC currently supports X requests per fixed time window (I assume), essentially allowing X requests at second 59 in minute 1 and X requests at second 1 in minute 2. I've worked with APIs that applied strategies like "leaky bucket" or similar to avoid potential bursts like that. I imagine one would be able to specify an option that influences the distribution of
Specifying that is not super crucial for me at the moment but might be for other customers. However, it is crucial for me to be able to limit executions not by minutes but seconds. I assume I'd be able to do that with a configuration like this?
Lastly Would probably choose |
Beta Was this translation helpful? Give feedback.
-
Agree! Let's prefer type safety to shorthands ✅
Definitely an interesting use case!
Providing some throttling strategies is definitely planned!
Noted 💯 |
Beta Was this translation helpful? Give feedback.
-
looks good. I much prefer the function based throttle configurations. easier to modify. I'm a bit confused by multi-group throttling—if you assign two throttle groups to a job, will it just pick the throttle config that has a lower number? e.g. it picks the lowest max number and the lowest concurrency number from all assigned groups? I imagined that jobs would only be part of one group. another way you could do it is with folders, which might be easier to reason about (this is how I initially imagined it, which seem natural in a SvelteKit context where file based routing is used) |
Beta Was this translation helpful? Give feedback.
-
I initially had the same confusion as @benwoodward for jobs belonging to multiple groups, and might have made a wrong assumption on how you plan to handle such. I assume that a job is only run when the rules for X groups are met. And, any job which cannot be run now is prioritized to run at the next possible moment even though a second job scheduled later could also be run at that exact moment. Is that the idea? Not being able to specify multiple groups could work, I guess, but would limit the number of API providers per worker to one? Hence, force me to split my code by the API providers I use. That might not be ideal if I wanted to split my workers by business processes, which, in our case, contains requests to multiple API providers. |
Beta Was this translation helpful? Give feedback.
-
@benwoodward @marcfalk, I agree that assigning background functions to multiple groups is unclear and does not bring much value (cc @gearnode: discussed earlier).
Agree, but we want to keep Defer as much as "framework-agnostic" as possible; we'll always prefer code-based configuration. -- Let's wait for comments from a few more people before moving to a planning proposal 🚀 |
Beta Was this translation helpful? Give feedback.
-
I certainly see the value. Just think it requires half a page of explanation on how Defer handles a job that is in two groups for which the job meets the limits of group #1 but does not meet the limits of group #2 (at this moment). I'd very much like to be able to divide my code by business process, and not have to force-split pieces of code that belongs together (from a DX and business point of view) into multiple jobs in order to throttle properly. I've tried to make some example code to illustrate the difference. In short I prefer this:
Over this (which comes with more overhead and complexity imo): Worker 1
Worker 2
Worker 3
Just wanted to make that clear ✌️ I do recognize that allowing only one group only is way simpler, and I'd be happy to go with that approach for now if it means we get throttling way sooner even though I'd have to refactor a lot of code on our end 😅 EDIT: Typos... |
Beta Was this translation helpful? Give feedback.
-
@charlypoly Any update on this feature? ✌️ |
Beta Was this translation helpful? Give feedback.
-
Request
https://discord.com/channels/1073595399186694185/1073595399958442096/1123572820564250765
Spec proposal
The first beta version could offer a static throttling configuration at the function level:
defer/enrichVerbatim.ts:
Throttling grouping
Throttling groups are defined once and can be shared between multiple functions, ex:
open-ai
that apply a60/min
throttling.defer/index.ts:
defer/enrichVerbatimToSlack.ts:
defer/enrichVerbatim.ts:
Please provide any feedback, request, or comment with some pseudo-code examples.
We'll be happy to answer any question!
Beta Was this translation helpful? Give feedback.
All reactions