-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
167 additions
and
52 deletions.
There are no files selected for viewing
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
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
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
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
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 |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { createClient, RedisClientType } from 'redis'; | ||
import { Rule } from '../types/rule'; | ||
import { NotifierEvent } from '../types/notifier-task'; | ||
|
||
/** | ||
* Class with helper functions for working with Redis | ||
*/ | ||
export default class RedisHelper { | ||
/** | ||
* Redis client for making queries | ||
*/ | ||
private readonly redisClient: RedisClientType; | ||
|
||
/** | ||
* Constructor of the Redis helper class | ||
* Initializes the Redis client and sets up error handling | ||
*/ | ||
constructor() { | ||
this.redisClient = createClient({ url: process.env.REDIS_URL }); | ||
|
||
this.redisClient.on('error', (error) => { | ||
console.error(error); | ||
}); | ||
} | ||
|
||
/** | ||
* Connect to redis client | ||
*/ | ||
public async initialize(): Promise<void> { | ||
await this.redisClient.connect(); | ||
} | ||
|
||
/** | ||
* Close redis client | ||
*/ | ||
public async close(): Promise<void> { | ||
if (this.redisClient.isOpen) { | ||
await this.redisClient.quit(); | ||
} | ||
} | ||
|
||
/** | ||
* Method that updates the event count respectfully to the threshold reset period | ||
* | ||
* @param ruleId - id of the rule used as a part of structure key | ||
* @param groupHash - event group hash used as a part of structure key | ||
* @param thresholdPeriod - period of time used to reset the event count | ||
* @returns {number} current event count | ||
*/ | ||
public async computeEventCountForPeriod(ruleId: string, groupHash: NotifierEvent['groupHash'], thresholdPeriod: Rule['eventThresholdPeriod']): Promise<number> { | ||
const script = ` | ||
local key = KEYS[1] | ||
local currentTimestamp = tonumber(ARGV[1]) | ||
local thresholdExpirationPeriod = tonumber(ARGV[2]) | ||
local startPeriodTimestamp = tonumber(redis.call("HGET", key, "timestamp")) | ||
if ((startPeriodTimestamp == nil) or (currentTimestamp >= startPeriodTimestamp + thresholdExpirationPeriod)) then | ||
redis.call("HSET", key, "timestamp", currentTimestamp) | ||
redis.call("HSET", key, "eventsCount", 0) | ||
end | ||
local newCounter = redis.call("HINCRBY", key, "eventsCount", 1) | ||
return newCounter | ||
`; | ||
|
||
const key = `${ruleId}:${groupHash}:${thresholdPeriod}:times`; | ||
|
||
const currentTimestamp = Date.now(); | ||
|
||
const currentEventCount = await this.redisClient.eval(script, { | ||
keys: [ key ], | ||
arguments: [currentTimestamp.toString(), (currentTimestamp + thresholdPeriod).toString()], | ||
}) as number; | ||
|
||
return (currentEventCount !== null) ? currentEventCount : 0; | ||
} | ||
} | ||
|