Rate Limit Based on Time

Output rate-limiting limits the number of events emitted by the queries based on a specified criterion such as time, and the number of events. This example provides some basic understanding of how rate limiting can be done based on time.

Refer the Siddhi query guide for more information.

define stream APIRequestStream (apiName string, version string,
    tier string, user string, userEmail string);
define stream UserNotificationStream (user string,
    apiName string, version string, tier string,
    userEmail string, throttledCount long);
@info(name='api-throttler')
from APIRequestStream#window.timeBatch(1 min, 0, true) 
select apiName, version, user, tier, userEmail,
    count() as totalRequestCount
group by apiName, version, user
having totalRequestCount == 3 or totalRequestCount == 0
insert all events into ThrottledStream;

@info(name='throttle-flag-generator') 
from ThrottledStream 
select apiName, version, user, tier, userEmail,
    ifThenElse(totalRequestCount == 0, false, true)
        as isThrottled
insert into ThrottleOutputStream;

@info(name='notification-generator') 
from ThrottleOutputStream[isThrottled]#window.time(1 hour) 
select user, apiName, version, tier, userEmail,
    count() as throttledCount
group by user, apiName, version, tier
having throttledCount > 2
output first every 15 min 
insert into UserNotificationStream;
define stream APIRequestStream (apiName string, version string,
    tier string, user string, userEmail string);

Defines APIRequestStream stream which contains the events regarding the API request.

define stream UserNotificationStream (user string,
    apiName string, version string, tier string,
    userEmail string, throttledCount long);

Defines UserNotificationStream stream which contains the notification events.

@info(name='api-throttler')
from APIRequestStream#window.timeBatch(1 min, 0, true) 
select apiName, version, user, tier, userEmail,
    count() as totalRequestCount
group by apiName, version, user
having totalRequestCount == 3 or totalRequestCount == 0
insert all events into ThrottledStream;

This query generates events when API is throttled and released from throttling. It generates a throttling event if an API is called more than 3 times in a minute.

@info(name='throttle-flag-generator') 
from ThrottledStream 
select apiName, version, user, tier, userEmail,
    ifThenElse(totalRequestCount == 0, false, true)
        as isThrottled

Create isThrottled flag based on the API request count

insert into ThrottleOutputStream;
@info(name='notification-generator') 
from ThrottleOutputStream[isThrottled]#window.time(1 hour) 
select user, apiName, version, tier, userEmail,
    count() as throttledCount
group by user, apiName, version, tier

This query helps to generate notifications to the user based on the API usage. User is notified to upgrade the subscription tier if he is frequently throttled.

having throttledCount > 2

Find the users who are throttled more than 2 times in an hour

output first every 15 min 

Notify the first occurrence when throttledCount > 2 for every 15 minutes.

insert into UserNotificationStream;

API throttling use case is considered in this example to explain the time-based rate limiting. API request events arrive through APIRequestStream stream. If there are more than 3 API requests sent by a user within 1 minute then the subsequence requests are getting throttled. And, if a user gets throttled more than 2 times within 1 hour then there is a notification event generated to notify the user to consider upgrading the subscription tier. In this case, the notification events are get rate limited based on time. For example, within 15 minutes there will be only one notification for an API, tier and user combination.

Input

Sent below three events to APIRequestStream stream for three minutes (three events for every minute),

['Get-Weather', '1.0.0', 'Gold', 'George', 'george@gmail.com']

['Get-Weather', '1.0.0', 'Gold', 'George', 'george@gmail.com']

['Get-Weather', '1.0.0', 'Gold', 'George', 'george@gmail.com']

Output

After processing, the event arriving at UserNotificationStream will be as follows:

['Get-Weather', '1.0.0', 'Gold', 'george@gmail.com', 3]

Top