fastify / fastify-throttle

Throttle the download speed of a request
Other
17 stars 5 forks source link

Possibility to retrieve request object in bytesPerSecond function #7

Closed dunklesToast closed 11 months ago

dunklesToast commented 11 months ago

Prerequisites

🚀 Feature Proposal

It’d be great if we could access the request object in the bytesPerSecond function so we can set the speed based on outer arguments.

Motivation

A possible use case could be throttling speeds for different user subscription tiers.

Example

Let’s say I have a req.user.plan field and want to throttle users depending on which plan they have, i currently see no way to implement this behavior. If the req object could be passed that’d be awesome.

Uzlopak commented 11 months ago

Are you referring to fastify/throttle?

dunklesToast commented 11 months ago

Are you referring to fastify/throttle?

Absolutely - sorry for the confusion. GitHub just sent me here when I clicked feature request in that repo and I anticipated it would carry that info over

Uzlopak commented 11 months ago

Interesting question. I have to think about a solution.

Less than passing request to bytesPerSecond, but passing a factoryFunction which gets the request and builds the bytesPerSecond Fn which is then used by fastify-throttle. We should not pass the request into bytesPerSecond, because the ThrottleStream should not know anything about the request object. Or else if we pass request into bytesPerSecond, we maybe have issues if we want to implement trottle groups.

dunklesToast commented 11 months ago

Fair point. For usage something like res.throttle(500 /** bytesPerSecond */).send(...) would be cool but not sure if thats possible with the current implementation.

This way we could allow users something like this:

let plans = {
  FREE: 500, // bytesPerSecond
  PREMIUM: 1000,
  TURBO: 2500
}

fastify.get('/download/:id', (req, res) => {
  const plan = await userservice.getUserPlan(req.user.id);
  const file = await fileservice.getFile(req.params.id);

  return res.throttle(plans[plan]).send(file);
});

However this would probably not allow us to change the speed mid-transfer but only at the start of the transfer so I am not sure if thats a great approach. Wdyt?

Uzlopak commented 11 months ago

I actually would change the bytesPerSecond function definition.

(req: FastifyRequest) => BytesPerSecondFn;

And then release a semver-major.

dunklesToast commented 11 months ago

(req: FastifyRequest) => BytesPerSecondFn;

That'd also be awesome. Could we also add support for BytesPerSecondFn to be async?

Uzlopak commented 11 months ago

sure

Uzlopak commented 11 months ago

Created PR #8

Uzlopak commented 11 months ago

v2.0.0 got released.