Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can you throttle calls server side?

Tags:

meteor

I know client side _underscore.js can be used to throttle click rates, but how do you throttle calls server side? I thought of using the same pattern but unfortunately _throttle doesn't seem to allow for differentiating between Meteor.userId()'s.

Meteor.methods({
  doSomething: function(arg1, arg2){
    // how can you throttle this without affecting ALL users
  }
);
like image 497
Stephan Tual Avatar asked Feb 04 '26 01:02

Stephan Tual


1 Answers

Here's a package I've roughed up - but not yet submitted to Atmosphere (waiting until I familiarize myself with tinytest and write up unit tests for it).

https://github.com/zeroasterisk/Meteor-Throttle

Feel free to play with it, extend, fix and contribute (pull requests encouraged)

The concept is quite simple, and it only runs (should only be run) on the server.

You would first need to come up with a unique key for what you want to throttle...

eg: Meteor.userId() + 'my-function-name' + 'whatever'

This system uses a new Collection 'throttle' and some helper methods to: check, set, and purge records. There is also a helper checkThenSet method which is actually the most common pattern, check if we can do something, and the set a record that we did.

Usage

(Use Case) If your app is sending emails, you wouldn't want to send the same email over and over again, even if a user triggered it.

// on server
if (!Throttle.checkThenSet(key, allowedCount, expireInSec)) {
  throw new Meteor.Error(500, 'You may only send ' + allowedCount + ' emails at a time, wait a while and try again');
}
....

On Throttle Methods

  • checkThenSet(key, allowedCount, expireInSec) checks a key, if passes it then sets the key for future checks
  • check(key, allowedCount) checks a key, if less than allowedCount of the (unexpired) records exist, it passes
  • set(key, expireInSec) sets a record for key, and it will expire after expireInSec seconds, eg: 60 = 1 min in the future
  • purge() expires all records which are no longer within timeframe (automatically called on every check)

Methods (call-able)

  • throttle(key, allowedCount, expireInSec) --> Throttle.checkThenSet()
  • throttle-check(key, allowedCount) --> Throttle.check()
  • throttle-set(key, expireInSec) --> Throttle.set()
like image 141
zeroasterisk Avatar answered Feb 05 '26 18:02

zeroasterisk



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!