forked from redislabs-training/ru102j
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Programming Challenge redislabs-training#7
- Loading branch information
1 parent
3390941
commit 54173bc
Showing
2 changed files
with
39 additions
and
20 deletions.
There are no files selected for viewing
56 changes: 39 additions & 17 deletions
56
src/main/java/com/redislabs/university/RU102J/dao/RateLimiterSlidingDaoRedisImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,46 @@ | ||
package com.redislabs.university.RU102J.dao; | ||
|
||
import com.redislabs.university.RU102J.core.KeyHelper; | ||
|
||
import java.time.ZonedDateTime; | ||
import java.util.UUID; | ||
|
||
import redis.clients.jedis.Jedis; | ||
import redis.clients.jedis.JedisPool; | ||
import redis.clients.jedis.Response; | ||
import redis.clients.jedis.Transaction; | ||
|
||
public class RateLimiterSlidingDaoRedisImpl implements RateLimiter { | ||
|
||
private final JedisPool jedisPool; | ||
private final long windowSizeMS; | ||
private final long maxHits; | ||
|
||
public RateLimiterSlidingDaoRedisImpl(JedisPool pool, long windowSizeMS, | ||
long maxHits) { | ||
this.jedisPool = pool; | ||
this.windowSizeMS = windowSizeMS; | ||
this.maxHits = maxHits; | ||
} | ||
|
||
// Challenge #7 | ||
@Override | ||
public void hit(String name) throws RateLimitExceededException { | ||
// START CHALLENGE #7 | ||
// END CHALLENGE #7 | ||
} | ||
private final JedisPool jedisPool; | ||
private final long windowSizeMS; | ||
private final long maxHits; | ||
|
||
public RateLimiterSlidingDaoRedisImpl( JedisPool pool, long windowSizeMS, long maxHits ) { | ||
this.jedisPool = pool; | ||
this.windowSizeMS = windowSizeMS; | ||
this.maxHits = maxHits; | ||
} | ||
|
||
// Challenge #7 | ||
@Override | ||
public void hit( String name ) throws RateLimitExceededException { | ||
// START CHALLENGE #7 | ||
try ( Jedis jedis = jedisPool.getResource(); Transaction t = jedis.multi() ) { | ||
long currentMs = ZonedDateTime.now().toInstant().toEpochMilli(); | ||
|
||
// make the member unique in order not to replace the score of another one | ||
String member = String.format( "%s:%s", currentMs, UUID.randomUUID() ); | ||
String key = KeyHelper.getKey( String.format( "limiter:%s:%s:maxHits", windowSizeMS, name ) ); | ||
t.zadd( key, currentMs, member ); | ||
t.zremrangeByScore( key, 0, currentMs - windowSizeMS ); // remove hits before the current sliding window | ||
Response<Long> hitCount = t.zcard( key ); | ||
t.exec(); | ||
|
||
if ( hitCount.get() > maxHits ) { | ||
throw new RateLimitExceededException(); | ||
} | ||
} | ||
// END CHALLENGE #7 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters