Skip to content

Conversation

@Feijs
Copy link
Collaborator

@Feijs Feijs commented Dec 21, 2016

Since we needed some other throttling behaviour than offered by the original, I've implemented a number of additional throttlers.

Changes:

  • Additional throttling algorithms: fixed window, moving window, leaky bucket and queue. See the readme for details.
  • A settings object for throttler settings, such as time and hit limit. This way the various throttlers can each have different parameters. The Data object does no longer need to contain these parameters, so have been removed.
  • CacheAdapter is now a dependency of ThrottlerFactory, instead of Ratelimiter
  • CacheThrottler has been renamed to ElasticWindowThrottler to reflect its implementation and be in line with the other throttler names.
  • Added a RatelimiterInterface
  • Fixed usage of the memcached config server settings
  • Added PHP 7 to the ci builds

It does necessarily contain a number of BC breaks. So if you are willing to merge this, I would suggest tagging the current code as a minor release (1.2) and the new code as a new major (2.0)

Sorry for the size of the PR and the interspersed fixes. If preferred I can squash and split the changes into smaller chuncks

Mike Feijs and others added 30 commits October 27, 2015 11:56
* (Re)add hydrator factory
* Inject factories as dependancies
* Allow throttler specific ttl & limit
* Expose throttler ttl & limit
Conflicts:
	src/RateLimiter.php
	src/Throttle/Throttler/CacheThrottler.php
* Corrected config indices for driver creator functions
* Added tests for (installed) driver creator functions
* Actually use config settings for mysql, memcache
Conflicts:
	README.md
	config/config.php
	src/Cache/Factory/DesarrollaCacheFactory.php
	src/Cache/Factory/FactoryInterface.php
	src/RateLimiter.php
	src/Throttle/Hydrator/FactoryInterface.php
	src/Throttle/Hydrator/HydratorFactory.php
	tests/Cache/Factory/DesarrollaCacheFactoryTest.php
Conflicts:
	src/Cache/Factory/DesarrollaCacheFactory.php
* Extracted time based functions
* Listener to validate mockery expectations
* Added optional threshold
* Throttler settings removed from Data to seperate classes
* CacheAdapter dependency moved from Ratelimiter to ThrottlerFactory
* Factory can now create LeakyBucketThrottler
* Interface Ratelimiter and use settings object
* Added various unit tests, moved functional tests
MWW-3452 - Leaky bucket ratelimiter
…vision by zero situation when tokenlimit == threshold
Fixes inconsistencies in (milli)seconds in LeakyBucketThrottler.
…n count before delay to allow for calls from multiple sources
@sunspikes
Copy link
Owner

@Feijs thank you!
i'll check & create a new release branch for this.

public function hit()
{
if (0 !== $waitTime = $this->internalThrottler->getRetryTimeout()) {
$this->timeProvider->usleep(1e3 * $waitTime);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be, better use a constant instead of magic number?

// Update the window start time if the previous window has passed, or no cached window exists
try {
if (($this->timeProvider->now() - $this->cache->get($this->key.self::TIME_CACHE_KEY)) > $this->timeLimit) {
$this->cache->set($this->key.self::TIME_CACHE_KEY, $this->timeProvider->now(), $this->cacheTtl);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think it's better to use namespaced pools instead of static key suffixes (It may be too much of a think to do btw) :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a functional benefit to using namespaces pools? Otherwise that's a bit overkill I think. It'll add the overhead of managing the pools.

{
const TIME_CACHE_KEY = ':time';
const HITS_CACHE_KEY = ':hits';

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the better name be like *_SUFFIX

public function clear()
{
$this->setCachedHitCount(0);
$this->cache->set($this->key.self::TIME_CACHE_KEY, $this->timeProvider->now(), $this->cacheTtl);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it better to use a helper method like 'prefixKey' or 'getTimeCacheKey' since same thing is done multiple times.

@sunspikes sunspikes merged commit 8563398 into sunspikes:master Jan 2, 2017
@sunspikes
Copy link
Owner

Thank you @Feijs once again!
I've created a new 1.0 branch for old stuff, this now in master, i'll do some cleanups

@Feijs
Copy link
Collaborator Author

Feijs commented Jan 3, 2017

Thats wonderfull, thanks! Sorry for the delay in response to your comments, I'll send in another PR soon to address those

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants