fix: add lock around redis commands

not locking these seems to make the library run into state issues, and since the rtt is currently <50ms this shouldn't cause significant delays
This commit is contained in:
shiftinv 2022-09-08 00:04:25 +02:00
parent c95b6fd5a3
commit 5adc6d8e3a
2 changed files with 17 additions and 9 deletions

View File

@ -2,4 +2,5 @@ export * as http from "https://deno.land/std@0.154.0/http/mod.ts";
export * as log from "https://deno.land/std@0.154.0/log/mod.ts";
export * as hex from "https://deno.land/std@0.154.0/encoding/hex.ts";
export * as redis from "https://deno.land/x/redis@v0.27.0/mod.ts";
export { Lock } from "https://deno.land/x/async@v1.1.5/mod.ts";
export { default as TTLCache } from "https://deno.land/x/ttl@1.0.1/mod.ts";

View File

@ -1,4 +1,4 @@
import { log, redis, TTLCache } from "../deps.ts";
import { Lock, log, redis, TTLCache } from "../deps.ts";
import config from "./config.ts";
const KEY_EXPIRY = 3; // seconds
@ -22,10 +22,12 @@ class LocalCommentManager implements CommentManager {
class RedisCommentManager implements CommentManager {
private connectOptions: redis.RedisConnectOptions;
private lock: Lock;
private _redis: Promise<redis.Redis> | undefined;
constructor(options: redis.RedisConnectOptions) {
this.connectOptions = options;
this.lock = new Lock();
}
// manual lazy init, redis.createLazyClient currently doesn't support pipelines :/
@ -40,16 +42,21 @@ class RedisCommentManager implements CommentManager {
}
async getAndIncrement(key: string): Promise<number> {
const redis = await this.redis();
key = `reviewcomment:${key}`;
await this.lock.acquire();
try {
const redis = await this.redis();
key = `reviewcomment:${key}`;
const pl = redis.pipeline();
pl.incr(key);
pl.expire(key, KEY_EXPIRY);
const results = await pl.flush();
const pl = redis.pipeline();
pl.incr(key);
pl.expire(key, KEY_EXPIRY);
const results = await pl.flush();
const newValue = results[0] as number;
return newValue - 1; // return old value
const newValue = results[0] as number;
return newValue - 1; // return old value
} finally {
this.lock.release();
}
}
}