Move redis code to middleware

This commit is contained in:
Ajay Ramachandran 2021-05-23 15:49:12 -04:00
parent 1b175d85c0
commit 799aef0b65
4 changed files with 50 additions and 37 deletions

View file

@ -0,0 +1,35 @@
import redis from "../utils/redis";
import { Logger } from "../utils/logger";
import { skipSegmentsHashKey, skipSegmentsKey } from "./redisKeys";
import { Service, VideoID, VideoIDHash } from "../types/segments.model";
async function get<T>(fetchFromDB: () => Promise<T[]>, key: string): Promise<T[]> {
const {err, reply} = await redis.getAsync(key);
if (!err && reply) {
try {
Logger.debug("Got data from redis: " + reply);
return JSON.parse(reply);
} catch (e) {
// If all else, continue on to fetching from the database
}
}
const data = await fetchFromDB();
redis.setAsync(key, JSON.stringify(data));
return data;
}
function clearVideoCache(videoInfo: { videoID: VideoID; hashedVideoID: VideoIDHash; service: Service; }) {
if (videoInfo) {
redis.delAsync(skipSegmentsKey(videoInfo.videoID, videoInfo.service));
redis.delAsync(skipSegmentsHashKey(videoInfo.hashedVideoID, videoInfo.service));
}
}
export const QueryCacher = {
get,
clearVideoCache
}

View file

@ -1,5 +1,4 @@
import { Request, Response } from 'express';
import { RedisClient } from 'redis';
import { config } from '../config';
import { db, privateDB } from '../databases/databases';
import { skipSegmentsHashKey, skipSegmentsKey } from '../middleware/redisKeys';
@ -9,8 +8,7 @@ import { getCategoryActionType } from '../utils/categoryInfo';
import { getHash } from '../utils/getHash';
import { getIP } from '../utils/getIP';
import { Logger } from '../utils/logger';
import redis from '../utils/redis';
import { getSkipSegmentsByHash } from './getSkipSegmentsByHash';
import { QueryCacher } from '../middleware/queryCacher'
async function prepareCategorySegments(req: Request, videoID: VideoID, category: Category, segments: DBSegment[], cache: SegmentCache = {shadowHiddenSegmentIPs: {}}): Promise<Segment[]> {
@ -133,10 +131,10 @@ async function getSegmentsFromDBByHash(hashedVideoIDPrefix: VideoIDHash, service
`SELECT "videoID", "startTime", "endTime", "votes", "locked", "UUID", "category", "videoDuration", "shadowHidden", "hashedVideoID" FROM "sponsorTimes"
WHERE "hashedVideoID" LIKE ? AND "service" = ? AND "hidden" = 0 ORDER BY "startTime"`,
[hashedVideoIDPrefix + '%', service]
);
) as Promise<DBSegment[]>;
if (hashedVideoIDPrefix.length === 4) {
return await getSegmentsFromDB(fetchFromDB, skipSegmentsHashKey(hashedVideoIDPrefix, service))
return await QueryCacher.get(fetchFromDB, skipSegmentsHashKey(hashedVideoIDPrefix, service))
}
return await fetchFromDB();
@ -149,27 +147,9 @@ async function getSegmentsFromDBByVideoID(videoID: VideoID, service: Service): P
`SELECT "startTime", "endTime", "votes", "locked", "UUID", "category", "videoDuration", "shadowHidden" FROM "sponsorTimes"
WHERE "videoID" = ? AND "service" = ? AND "hidden" = 0 ORDER BY "startTime"`,
[videoID, service]
);
) as Promise<DBSegment[]>;
return await getSegmentsFromDB(fetchFromDB, skipSegmentsKey(videoID, service))
}
async function getSegmentsFromDB(fetchFromDB: () => Promise<DBSegment[]>, key: string): Promise<DBSegment[]> {
const {err, reply} = await redis.getAsync(key);
if (!err && reply) {
try {
Logger.debug("Got data from redis: " + reply);
return JSON.parse(reply);
} catch (e) {
// If all else, continue on to fetching from the database
}
}
const data = await fetchFromDB();
redis.setAsync(key, JSON.stringify(data));
return data;
return await QueryCacher.get(fetchFromDB, skipSegmentsKey(videoID, service))
}
//gets a weighted random choice from the choices array based on their `votes` property.

View file

@ -16,6 +16,7 @@ import redis from '../utils/redis';
import { Category, CategoryActionType, IncomingSegment, Segment, SegmentUUID, Service, VideoDuration, VideoID } from '../types/segments.model';
import { deleteLockCategories } from './deleteLockCategories';
import { getCategoryActionType } from '../utils/categoryInfo';
import { QueryCacher } from '../middleware/queryCacher';
interface APIVideoInfo {
err: string | boolean,
@ -528,8 +529,11 @@ export async function postSkipSegments(req: Request, res: Response) {
await privateDB.prepare('run', `INSERT INTO "sponsorTimes" VALUES(?, ?, ?)`, [videoID, hashedIP, timeSubmitted]);
// Clear redis cache for this video
redis.delAsync(skipSegmentsKey(videoID, service));
redis.delAsync(skipSegmentsHashKey(hashedVideoID, service));
QueryCacher.clearVideoCache({
videoID,
hashedVideoID,
service
});
} catch (err) {
//a DB change probably occurred
res.sendStatus(500);

View file

@ -15,6 +15,7 @@ import redis from '../utils/redis';
import { skipSegmentsHashKey, skipSegmentsKey } from '../middleware/redisKeys';
import { Category, CategoryActionType, HashedIP, IPAddress, SegmentUUID, Service, VideoID, VideoIDHash } from '../types/segments.model';
import { getCategoryActionType } from '../utils/categoryInfo';
import { QueryCacher } from '../middleware/queryCacher';
const voteTypes = {
normal: 0,
@ -230,7 +231,7 @@ async function categoryVote(UUID: SegmentUUID, userID: UserID, isVIP: boolean, i
}
}
clearRedisCache(videoInfo);
QueryCacher.clearVideoCache(videoInfo);
res.sendStatus(finalResponse.finalStatus);
}
@ -416,7 +417,7 @@ export async function voteOnSponsorTime(req: Request, res: Response) {
await db.prepare('run', 'UPDATE "sponsorTimes" SET locked = 0 WHERE "UUID" = ?', [UUID]);
}
clearRedisCache(videoInfo);
QueryCacher.clearVideoCache(videoInfo);
//for each positive vote, see if a hidden submission can be shown again
if (incrementAmount > 0 && voteTypeEnum === voteTypes.normal) {
@ -466,10 +467,3 @@ export async function voteOnSponsorTime(req: Request, res: Response) {
res.status(500).json({error: 'Internal error creating segment vote'});
}
}
function clearRedisCache(videoInfo: { videoID: VideoID; hashedVideoID: VideoIDHash; service: Service; }) {
if (videoInfo) {
redis.delAsync(skipSegmentsKey(videoInfo.videoID, videoInfo.service));
redis.delAsync(skipSegmentsHashKey(videoInfo.hashedVideoID, videoInfo.service));
}
}