Skip to content

Commit

Permalink
Register own listener for errors
Browse files Browse the repository at this point in the history
  • Loading branch information
dex4er committed Aug 6, 2019
1 parent da13f7c commit b47f3cd
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 4 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## v4.1.0 2019-08-06

- Safe limiter registers own listener for `error` event so errors are ignored
by default.

## v4.0.0 2019-07-11

- Breaking change: `interval` parameter is milliseconds now.
Expand Down
9 changes: 6 additions & 3 deletions src/safe-redis-sliding-window-rate-limiter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export interface SafeRedisSlidingWindowRateLimiter {

export class SafeRedisSlidingWindowRateLimiter extends RedisSlidingWindowRateLimiter
implements SlidingWindowRateLimiterBackend {
readonly reuseRedisAfter: number
readonly reuseRedisAfter = Number(this.options.reuseRedisAfter) || 2000

private redisServiceAvailable = true

Expand All @@ -36,8 +36,7 @@ export class SafeRedisSlidingWindowRateLimiter extends RedisSlidingWindowRateLim

constructor(readonly options: SafeRedisSlidingWindowRateLimiterOptions = {}) {
super(options)

this.reuseRedisAfter = Number(options.reuseRedisAfter) || 2000
this.on("error", this.errorHandler)
}

cancel(key: string, token: number): Promise<CancelResult> {
Expand Down Expand Up @@ -90,6 +89,10 @@ export class SafeRedisSlidingWindowRateLimiter extends RedisSlidingWindowRateLim
this.removeAllListeners("error")
}

private errorHandler(_error: Error): void {
// ignore
}

private handleError(error: Error): void {
this.markServiceAsUnavailable()
this.emit("error", error)
Expand Down
47 changes: 46 additions & 1 deletion test/redis-failure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {CheckResult, Redis, ReserveResult, SafeRedisSlidingWindowRateLimiter} fr
import {MockIORedis} from "./lib/mock-ioredis"

Feature("Test sliding-window-rate-limiter Redis failure with safe backend", () => {
Scenario("Redis failure", () => {
Scenario("Redis failure with error listener", () => {
const defaultLimit = 1
const errors: Error[] = []

Expand Down Expand Up @@ -66,4 +66,49 @@ Feature("Test sliding-window-rate-limiter Redis failure with safe backend", () =
expect(errors.length).to.equal(1)
})
})

Scenario("Redis failure without error listener", () => {
const defaultLimit = 1

let checkResult: CheckResult
let key: string
let limiter: SafeRedisSlidingWindowRateLimiter
let redis: Redis
let reserveResult: ReserveResult

Given("redis connection", () => {
redis = new MockIORedis()
})

And("limiter object", () => {
limiter = new SafeRedisSlidingWindowRateLimiter({
interval: 1,
redis,
})
})

And("key", () => {
key = "redis-failure:" + uuidv1()
})

When("Redis is disconnected", () => {
redis.disconnect()
})

And("check method is called", async () => {
checkResult = await limiter.check(key, defaultLimit)
})

Then("usage is 0", async () => {
expect(checkResult.usage).to.equal(0)
})

When("reserve method is called", async () => {
reserveResult = await limiter.reserve(key, defaultLimit)
})

Then("usage is 0", async () => {
expect(reserveResult.usage).to.equal(0)
})
})
})

0 comments on commit b47f3cd

Please sign in to comment.