From 23b846c9ea22a46df2f457bcb2ecec18ed260a5a Mon Sep 17 00:00:00 2001 From: AnxietyisReal <96593068+AnxietyisReal@users.noreply.github.com> Date: Tue, 3 Oct 2023 09:40:03 +1100 Subject: [PATCH] Add support for Redis --- .pnp.cjs | 157 ++++++++++++++++++++++++++++++++++++ docker-compose.yml | 6 ++ package.json | 1 + src/client.ts | 2 + src/commands/bannedWords.ts | 2 +- src/commands/mp.ts | 4 +- src/commands/tag.ts | 18 ++++- src/funcs/CacheServer.ts | 54 +++++++++++++ src/funcs/DatabaseServer.ts | 1 + src/index.ts | 4 +- src/models/MPServer.ts | 21 +++++ src/models/bannedWords.ts | 21 +++++ src/models/punishments.ts | 23 +++++- src/models/tagSystem.ts | 29 +++++++ src/typings/interfaces.d.ts | 1 + yarn.lock | 87 +++++++++++++++++++- 16 files changed, 420 insertions(+), 11 deletions(-) create mode 100644 docker-compose.yml create mode 100644 src/funcs/CacheServer.ts diff --git a/.pnp.cjs b/.pnp.cjs index 85d9922..4a88854 100644 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -42,6 +42,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["mongoose", "npm:7.5.3"],\ ["ms", "npm:2.1.3"],\ ["prism-media", "virtual:20c353e2d6536e37339997f03975c6a660f4d296e664d291bd43620c6162cca8eb5ef90b0998dc9db75ff6862e5da587d0530bae26805f5fadc8f17aaa4ff794#npm:1.3.5"],\ + ["redis", "npm:4.6.10"],\ ["systeminformation", "npm:5.21.9"],\ ["typescript", "patch:typescript@npm%3A5.2.2#~builtin::version=5.2.2&hash=f3b441"],\ ["xml-js", "npm:1.6.11"],\ @@ -482,6 +483,128 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD"\ }]\ ]],\ + ["@redis/bloom", [\ + ["npm:1.2.0", {\ + "packageLocation": "./.yarn/cache/@redis-bloom-npm-1.2.0-c3ffcb341a-8c21422728.zip/node_modules/@redis/bloom/",\ + "packageDependencies": [\ + ["@redis/bloom", "npm:1.2.0"]\ + ],\ + "linkType": "SOFT"\ + }],\ + ["virtual:937ea26aedbee205c68895919d7db8dbc9e303224dcbaaefe04eb40b8bc08196e1e9bb312438a418bb05fd43aa448b8a1a888c15d44abf31570f5ab6c6ceaf1c#npm:1.2.0", {\ + "packageLocation": "./.yarn/__virtual__/@redis-bloom-virtual-0f3e79e21e/0/cache/@redis-bloom-npm-1.2.0-c3ffcb341a-8c21422728.zip/node_modules/@redis/bloom/",\ + "packageDependencies": [\ + ["@redis/bloom", "virtual:937ea26aedbee205c68895919d7db8dbc9e303224dcbaaefe04eb40b8bc08196e1e9bb312438a418bb05fd43aa448b8a1a888c15d44abf31570f5ab6c6ceaf1c#npm:1.2.0"],\ + ["@redis/client", "npm:1.5.11"],\ + ["@types/redis__client", null]\ + ],\ + "packagePeers": [\ + "@redis/client",\ + "@types/redis__client"\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ + ["@redis/client", [\ + ["npm:1.5.11", {\ + "packageLocation": "./.yarn/cache/@redis-client-npm-1.5.11-79133d887c-10f25a74f1.zip/node_modules/@redis/client/",\ + "packageDependencies": [\ + ["@redis/client", "npm:1.5.11"],\ + ["cluster-key-slot", "npm:1.1.2"],\ + ["generic-pool", "npm:3.9.0"],\ + ["yallist", "npm:4.0.0"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ + ["@redis/graph", [\ + ["npm:1.1.0", {\ + "packageLocation": "./.yarn/cache/@redis-graph-npm-1.1.0-84c3d1d722-d3df807108.zip/node_modules/@redis/graph/",\ + "packageDependencies": [\ + ["@redis/graph", "npm:1.1.0"]\ + ],\ + "linkType": "SOFT"\ + }],\ + ["virtual:937ea26aedbee205c68895919d7db8dbc9e303224dcbaaefe04eb40b8bc08196e1e9bb312438a418bb05fd43aa448b8a1a888c15d44abf31570f5ab6c6ceaf1c#npm:1.1.0", {\ + "packageLocation": "./.yarn/__virtual__/@redis-graph-virtual-bb08a73ddc/0/cache/@redis-graph-npm-1.1.0-84c3d1d722-d3df807108.zip/node_modules/@redis/graph/",\ + "packageDependencies": [\ + ["@redis/graph", "virtual:937ea26aedbee205c68895919d7db8dbc9e303224dcbaaefe04eb40b8bc08196e1e9bb312438a418bb05fd43aa448b8a1a888c15d44abf31570f5ab6c6ceaf1c#npm:1.1.0"],\ + ["@redis/client", "npm:1.5.11"],\ + ["@types/redis__client", null]\ + ],\ + "packagePeers": [\ + "@redis/client",\ + "@types/redis__client"\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ + ["@redis/json", [\ + ["npm:1.0.6", {\ + "packageLocation": "./.yarn/cache/@redis-json-npm-1.0.6-fc7bbce89a-9fda29abc3.zip/node_modules/@redis/json/",\ + "packageDependencies": [\ + ["@redis/json", "npm:1.0.6"]\ + ],\ + "linkType": "SOFT"\ + }],\ + ["virtual:937ea26aedbee205c68895919d7db8dbc9e303224dcbaaefe04eb40b8bc08196e1e9bb312438a418bb05fd43aa448b8a1a888c15d44abf31570f5ab6c6ceaf1c#npm:1.0.6", {\ + "packageLocation": "./.yarn/__virtual__/@redis-json-virtual-14ef713613/0/cache/@redis-json-npm-1.0.6-fc7bbce89a-9fda29abc3.zip/node_modules/@redis/json/",\ + "packageDependencies": [\ + ["@redis/json", "virtual:937ea26aedbee205c68895919d7db8dbc9e303224dcbaaefe04eb40b8bc08196e1e9bb312438a418bb05fd43aa448b8a1a888c15d44abf31570f5ab6c6ceaf1c#npm:1.0.6"],\ + ["@redis/client", "npm:1.5.11"],\ + ["@types/redis__client", null]\ + ],\ + "packagePeers": [\ + "@redis/client",\ + "@types/redis__client"\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ + ["@redis/search", [\ + ["npm:1.1.5", {\ + "packageLocation": "./.yarn/cache/@redis-search-npm-1.1.5-29c39f911a-f81771a712.zip/node_modules/@redis/search/",\ + "packageDependencies": [\ + ["@redis/search", "npm:1.1.5"]\ + ],\ + "linkType": "SOFT"\ + }],\ + ["virtual:937ea26aedbee205c68895919d7db8dbc9e303224dcbaaefe04eb40b8bc08196e1e9bb312438a418bb05fd43aa448b8a1a888c15d44abf31570f5ab6c6ceaf1c#npm:1.1.5", {\ + "packageLocation": "./.yarn/__virtual__/@redis-search-virtual-c4096b39ed/0/cache/@redis-search-npm-1.1.5-29c39f911a-f81771a712.zip/node_modules/@redis/search/",\ + "packageDependencies": [\ + ["@redis/search", "virtual:937ea26aedbee205c68895919d7db8dbc9e303224dcbaaefe04eb40b8bc08196e1e9bb312438a418bb05fd43aa448b8a1a888c15d44abf31570f5ab6c6ceaf1c#npm:1.1.5"],\ + ["@redis/client", "npm:1.5.11"],\ + ["@types/redis__client", null]\ + ],\ + "packagePeers": [\ + "@redis/client",\ + "@types/redis__client"\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ + ["@redis/time-series", [\ + ["npm:1.0.5", {\ + "packageLocation": "./.yarn/cache/@redis-time-series-npm-1.0.5-5df2dd2005-6bbdb0b793.zip/node_modules/@redis/time-series/",\ + "packageDependencies": [\ + ["@redis/time-series", "npm:1.0.5"]\ + ],\ + "linkType": "SOFT"\ + }],\ + ["virtual:937ea26aedbee205c68895919d7db8dbc9e303224dcbaaefe04eb40b8bc08196e1e9bb312438a418bb05fd43aa448b8a1a888c15d44abf31570f5ab6c6ceaf1c#npm:1.0.5", {\ + "packageLocation": "./.yarn/__virtual__/@redis-time-series-virtual-63c6e225a8/0/cache/@redis-time-series-npm-1.0.5-5df2dd2005-6bbdb0b793.zip/node_modules/@redis/time-series/",\ + "packageDependencies": [\ + ["@redis/time-series", "virtual:937ea26aedbee205c68895919d7db8dbc9e303224dcbaaefe04eb40b8bc08196e1e9bb312438a418bb05fd43aa448b8a1a888c15d44abf31570f5ab6c6ceaf1c#npm:1.0.5"],\ + ["@redis/client", "npm:1.5.11"],\ + ["@types/redis__client", null]\ + ],\ + "packagePeers": [\ + "@redis/client",\ + "@types/redis__client"\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["@sapphire/async-queue", [\ ["npm:1.5.0", {\ "packageLocation": "./.yarn/cache/@sapphire-async-queue-npm-1.5.0-f065e42c78-983dbd1fd1.zip/node_modules/@sapphire/async-queue/",\ @@ -814,6 +937,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD"\ }]\ ]],\ + ["cluster-key-slot", [\ + ["npm:1.1.2", {\ + "packageLocation": "./.yarn/cache/cluster-key-slot-npm-1.1.2-0571a28825-be0ad2d262.zip/node_modules/cluster-key-slot/",\ + "packageDependencies": [\ + ["cluster-key-slot", "npm:1.1.2"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["color-convert", [\ ["npm:2.0.1", {\ "packageLocation": "./.yarn/cache/color-convert-npm-2.0.1-79730e935b-79e6bdb9fd.zip/node_modules/color-convert/",\ @@ -914,6 +1046,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["mongoose", "npm:7.5.3"],\ ["ms", "npm:2.1.3"],\ ["prism-media", "virtual:20c353e2d6536e37339997f03975c6a660f4d296e664d291bd43620c6162cca8eb5ef90b0998dc9db75ff6862e5da587d0530bae26805f5fadc8f17aaa4ff794#npm:1.3.5"],\ + ["redis", "npm:4.6.10"],\ ["systeminformation", "npm:5.21.9"],\ ["typescript", "patch:typescript@npm%3A5.2.2#~builtin::version=5.2.2&hash=f3b441"],\ ["xml-js", "npm:1.6.11"],\ @@ -1319,6 +1452,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD"\ }]\ ]],\ + ["generic-pool", [\ + ["npm:3.9.0", {\ + "packageLocation": "./.yarn/cache/generic-pool-npm-3.9.0-21fff1a77f-3d89e9b201.zip/node_modules/generic-pool/",\ + "packageDependencies": [\ + ["generic-pool", "npm:3.9.0"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["genius-lyrics", [\ ["npm:4.4.6", {\ "packageLocation": "./.yarn/cache/genius-lyrics-npm-4.4.6-beff04ebb7-05a7420c75.zip/node_modules/genius-lyrics/",\ @@ -2291,6 +2433,21 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD"\ }]\ ]],\ + ["redis", [\ + ["npm:4.6.10", {\ + "packageLocation": "./.yarn/cache/redis-npm-4.6.10-937ea26aed-eae6e10f6e.zip/node_modules/redis/",\ + "packageDependencies": [\ + ["redis", "npm:4.6.10"],\ + ["@redis/bloom", "virtual:937ea26aedbee205c68895919d7db8dbc9e303224dcbaaefe04eb40b8bc08196e1e9bb312438a418bb05fd43aa448b8a1a888c15d44abf31570f5ab6c6ceaf1c#npm:1.2.0"],\ + ["@redis/client", "npm:1.5.11"],\ + ["@redis/graph", "virtual:937ea26aedbee205c68895919d7db8dbc9e303224dcbaaefe04eb40b8bc08196e1e9bb312438a418bb05fd43aa448b8a1a888c15d44abf31570f5ab6c6ceaf1c#npm:1.1.0"],\ + ["@redis/json", "virtual:937ea26aedbee205c68895919d7db8dbc9e303224dcbaaefe04eb40b8bc08196e1e9bb312438a418bb05fd43aa448b8a1a888c15d44abf31570f5ab6c6ceaf1c#npm:1.0.6"],\ + ["@redis/search", "virtual:937ea26aedbee205c68895919d7db8dbc9e303224dcbaaefe04eb40b8bc08196e1e9bb312438a418bb05fd43aa448b8a1a888c15d44abf31570f5ab6c6ceaf1c#npm:1.1.5"],\ + ["@redis/time-series", "virtual:937ea26aedbee205c68895919d7db8dbc9e303224dcbaaefe04eb40b8bc08196e1e9bb312438a418bb05fd43aa448b8a1a888c15d44abf31570f5ab6c6ceaf1c#npm:1.0.5"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["retry", [\ ["npm:0.12.0", {\ "packageLocation": "./.yarn/cache/retry-npm-0.12.0-72ac7fb4cc-623bd7d2e5.zip/node_modules/retry/",\ diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..d42baaa --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,6 @@ +services: + cache: + container_name: redis-cache + image: redis/redis-stack-server:7.2.0-v2 + ports: + - 6379:6379/tcp \ No newline at end of file diff --git a/package.json b/package.json index 5eae67a..5b3f7d3 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "mongoose": "7.5.3", "ms": "2.1.3", "prism-media": "1.3.5", + "redis": "4.6.10", "systeminformation": "5.21.9", "typescript": "5.2.2", "xml-js": "1.6.11", diff --git a/src/client.ts b/src/client.ts index 6412671..d9ca997 100644 --- a/src/client.ts +++ b/src/client.ts @@ -18,6 +18,7 @@ import tags from './models/tagSystem.js'; import bonkCount from './models/bonkCount.js'; import MPServer from './models/MPServer.js'; import DatabaseServer from './funcs/DatabaseServer.js'; +import CacheServer from './funcs/CacheServer.js'; import xjs from 'xml-js'; import moment from 'moment'; const tokens = JSON.parse(readFileSync('src/tokens.json', 'utf8')); @@ -95,6 +96,7 @@ export default class TClient extends Discord.Client { } async init(){ console.time('Startup'); + CacheServer.init(); DatabaseServer.init(); this.login(this.tokens.main); for (const file of readdirSync('dist/events')){ diff --git a/src/commands/bannedWords.ts b/src/commands/bannedWords.ts index b9bddec..fff2b88 100644 --- a/src/commands/bannedWords.ts +++ b/src/commands/bannedWords.ts @@ -18,7 +18,7 @@ export default { interaction.reply(`Successfully removed \`${word}\` from the database.`) }, view: async()=>{ - const findAll = await client.bannedWords._content.find({}); + const findAll = await client.bannedWords.findInCache(); writeFileSync('src/database/bw_dump.json', JSON.stringify(findAll.map(i=>i._id), null, 2), {encoding: 'utf8', flag: 'w+'}); interaction.reply({content: 'Here\'s the dump file from the database.', files: ['src/database/bw_dump.json'], ephemeral: true}).catch(err=>interaction.reply({content: `Ran into an error, notify <@&${client.config.mainServer.roles.bottech}> if it happens again:\n\`${err.message}\``, ephemeral: true})) } diff --git a/src/commands/mp.ts b/src/commands/mp.ts index 46405a9..3ef9fbe 100644 --- a/src/commands/mp.ts +++ b/src/commands/mp.ts @@ -20,7 +20,7 @@ export default { const serverSelector = interaction.options.getString('server'); if (['468835769092669461', '1149238561934151690'].includes(interaction.channelId) && !client.isStaff(interaction.member) && ['status', 'players'].includes(interaction.options.getSubcommand())) return interaction.reply('Please use <#739084625862852715> for `/mp status/players` commands to prevent clutter in this channel.').then(()=>setTimeout(()=>interaction.deleteReply(), 6000)); - const database = await client.MPServer._content.findById(interaction.guildId); + const database = await client.MPServer.findInCache(interaction.guildId); const endpoint = await fetch(database[serverSelector].ip+'/feed/dedicated-server-stats.json?code='+database[serverSelector].code, {signal: AbortSignal.timeout(7500),headers:{'User-Agent':'Daggerbot - MPdata/undici'}}).then(r=>r.json() as Promise); const embed = new client.embed(); ({ @@ -195,7 +195,7 @@ export default { const address = interaction.options.getString('address'); if (!address){ try { - const Url = await client.MPServer._content.findById(interaction.guildId); + const Url = await client.MPServer.findInCache(interaction.guildId); if (Url[serverSelector].ip && Url[serverSelector].code) return interaction.reply(Url[serverSelector].ip+'/feed/dedicated-server-stats.json?code='+Url[serverSelector].code) } catch(err){ Logger.forwardToConsole('error', 'MPDB', err); diff --git a/src/commands/tag.ts b/src/commands/tag.ts index 77d7663..40f5b80 100644 --- a/src/commands/tag.ts +++ b/src/commands/tag.ts @@ -3,7 +3,7 @@ import TClient from '../client.js'; import MessageTool from '../helpers/MessageTool.js'; export default { async autocomplete(client: TClient, interaction: Discord.AutocompleteInteraction){ - const array = (await client.tags?._content.find())?.map(x=>x._id).filter(c=>c.startsWith(interaction.options.getFocused())); + const array = (await client.tags?.findInCache())?.map(x=>x._id).filter(c=>c.startsWith(interaction.options.getFocused())); await interaction?.respond(array?.map(c=>({name: c, value: c}))); // If you question all those '?.', let me tell you: Discord.JS is fricking stupid and I am too stressed to find a solution for it. }, @@ -42,16 +42,26 @@ export default { name: interaction.user.username } }) - .then(()=>interaction.reply('Tag is now created and available to use.')) + .then(()=>{ + interaction.reply('Tag successfully created, should be available in a few seconds!') + client.tags.updateCache(); + }) .catch(err=>interaction.reply(`There was an error while trying to create your tag:\n\`\`\`${err}\`\`\``)), - delete: async()=>await client.tags._content.findByIdAndDelete(interaction.options.getString('name')).then(()=>interaction.reply('Tag successfully deleted.')).catch(err=>interaction.reply(`Failed to delete the tag:\n\`\`\`${err}\`\`\``)), + delete: async()=>await client.tags._content.findByIdAndDelete(interaction.options.getString('name')) + .then(()=>{ + interaction.reply('Tag successfully deleted.') + client.tags.updateCache(); + }).catch(err=>interaction.reply(`Failed to delete the tag:\n\`\`\`${err}\`\`\``)), edit: async()=>await client.tags._content.findByIdAndUpdate(interaction.options.getString('name'), { $set: { message: interaction.options.getString('new-message').replaceAll(/\\n/g, '\n'), embedBool: interaction.options.getBoolean('embed') } }) - .then(()=>interaction.reply('Tag successfully updated, enjoy!')) + .then(()=>{ + interaction.reply('Tag successfully updated, enjoy!') + client.tags.updateCache(); + }) .catch(err=>interaction.reply(`Tag couldn\'t be updated:\n\`\`\`${err}\`\`\``)) } as any)[interaction.options.getSubcommand() ?? interaction.options.getSubcommandGroup()](); }, diff --git a/src/funcs/CacheServer.ts b/src/funcs/CacheServer.ts new file mode 100644 index 0000000..9c450c8 --- /dev/null +++ b/src/funcs/CacheServer.ts @@ -0,0 +1,54 @@ +import {createClient, ErrorReply} from 'redis'; +import Logger from '../helpers/Logger.js'; +import {readFileSync} from 'node:fs'; +import {promisify} from 'node:util'; +import {Tokens} from '../typings/interfaces'; +const tokens:Tokens = JSON.parse(readFileSync('src/tokens.json', 'utf-8')); + +let Prefix = 'Cache'; +const RedisClient = createClient({ + url: tokens.redis_uri, + database: 0, + name: 'Daggerbot', + socket: { + keepAlive: 15000, + timeout: 30000 + } +}); + +export default class CacheServer { + protected static eventManager() { + RedisClient + .on('connect', ()=>Logger.forwardToConsole('log', Prefix, 'Connection to Redis has been established')) + .on('error', (err:ErrorReply)=>Logger.forwardToConsole('error', Prefix, `Encountered an error in Redis: ${err.message}`)) + } + protected static async connect() { + await RedisClient.connect(); + } + static async get(key:any) { + const cachedResult = await RedisClient.get(key); + if (cachedResult) { + Logger.forwardToConsole('log', Prefix, `Cache hit for ${key}`); + return JSON.parse(cachedResult); + } else { + Logger.forwardToConsole('log', Prefix, `Cache miss for ${key}`); + return null + } + } + static async set(key:any, value:any) { + Logger.forwardToConsole('log', Prefix, `Building cache for ${key}`); + return await RedisClient.set(key, JSON.stringify(value)); + } + static async expiry(key:any, time:number) { + Logger.forwardToConsole('log', Prefix, `Setting expiration for ${key} to ${time} seconds`); + return await RedisClient.expire(key, time); + } + static async delete(key:any) { + Logger.forwardToConsole('log', Prefix, `Deleting cache for ${key}`); + return await RedisClient.del(key); + } + static init() { + this.connect(); + this.eventManager(); + } +} diff --git a/src/funcs/DatabaseServer.ts b/src/funcs/DatabaseServer.ts index e131aa7..63ee3c0 100644 --- a/src/funcs/DatabaseServer.ts +++ b/src/funcs/DatabaseServer.ts @@ -1,5 +1,6 @@ import mongoose from 'mongoose'; import Logger from '../helpers/Logger.js'; +import CacheServer from './CacheServer.js'; import {readFileSync} from 'node:fs'; import {Tokens} from '../typings/interfaces'; const tokens:Tokens = JSON.parse(readFileSync('src/tokens.json', 'utf-8')); diff --git a/src/index.ts b/src/index.ts index 3553cac..06ffd5d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -36,7 +36,7 @@ if (client.config.botSwitches.music){ // YouTube Upload notification and MP loop if (client.config.botSwitches.mpstats) setInterval(async()=>{ - const serverlake = (await client.MPServer._content.findById(client.config.mainServer.id)); + const serverlake = (await client.MPServer.findInCache(client.config.mainServer.id)); for await (const [locName, locArea] of Object.entries(client.config.MPStatsLocation)) await MPModule(client, locArea.channel, locArea.message, serverlake[locName], locName) }, 35000); setInterval(async()=>{// Ping notification is currently WIP, it might be active in production but I want to see how it goes with role mentions first so I can make any further changes. @@ -48,7 +48,7 @@ setInterval(async()=>{// Ping notification is currently WIP, it might be active setInterval(async()=>{ const now = Date.now(); - const punishments = await client.punishments._content.find(); + const punishments = await client.punishments.findInCache(); punishments.filter(x=>x.endTime && x.endTime<= now && !x.expired).forEach(async punishment=>{ Logger.forwardToConsole('log', 'Punishment', `${punishment.member}\'s ${punishment.type} should expire now`); Logger.forwardToConsole('log', 'Punishment', await client.punishments.removePunishment(punishment._id, client.user.id, 'Time\'s up!')); diff --git a/src/models/MPServer.ts b/src/models/MPServer.ts index fc83a4d..c2bce24 100644 --- a/src/models/MPServer.ts +++ b/src/models/MPServer.ts @@ -1,5 +1,6 @@ import TClient from '../client.js'; import mongoose from 'mongoose'; +import CacheServer from '../funcs/CacheServer.js'; const Schema = mongoose.model('mpserver', new mongoose.Schema({ _id: {type: String, required:true}, @@ -21,4 +22,24 @@ export default class MPServer extends Schema { this.client = client; this._content = Schema; } + async findInCache(query:any): Promise { + const cacheKey = `MPServer:${query}`; + const cachedResult = await CacheServer.get(cacheKey); + let result; + if (cachedResult) { + try { + result = cachedResult; + } catch (error) { + console.error('Error parsing cached result:', error); + result = await this._content.findById(query); + CacheServer.set(cacheKey, result); + CacheServer.expiry(cacheKey, 1800); + } + } else { + result = await this._content.findById(query); + CacheServer.set(cacheKey, result); + CacheServer.expiry(cacheKey, 1800); + } + return result; + } } diff --git a/src/models/bannedWords.ts b/src/models/bannedWords.ts index 2fdc26a..bb6c5f2 100644 --- a/src/models/bannedWords.ts +++ b/src/models/bannedWords.ts @@ -1,5 +1,6 @@ import TClient from '../client.js'; import mongoose from 'mongoose'; +import CacheServer from '../funcs/CacheServer.js'; const Schema = mongoose.model('bannedWords', new mongoose.Schema({ _id: {type: String, required:true} @@ -13,4 +14,24 @@ export default class bannedWords extends Schema { this.client = client; this._content = Schema; } + async findInCache(): Promise { + const cacheKey = 'bannedWords'; + const cachedResult = await CacheServer.get(cacheKey); + let result; + if (cachedResult) { + try { + result = cachedResult; + } catch (error) { + console.error('Error parsing cached result:', error); + result = await this._content.find(); + CacheServer.set(cacheKey, result); + CacheServer.expiry(cacheKey, 180); + } + } else { + result = await this._content.find(); + CacheServer.set(cacheKey, result); + CacheServer.expiry(cacheKey, 180); + } + return result; + } } diff --git a/src/models/punishments.ts b/src/models/punishments.ts index e3f043c..ad977cb 100644 --- a/src/models/punishments.ts +++ b/src/models/punishments.ts @@ -1,6 +1,7 @@ import Discord from 'discord.js'; import TClient from '../client.js'; import mongoose from 'mongoose'; +import CacheServer from '../funcs/CacheServer.js'; import ms from 'ms'; import FormatTime from '../helpers/FormatTime.js'; import {Punishment} from '../typings/interfaces'; @@ -26,7 +27,27 @@ export default class punishments extends Schema { this.client = client; this._content = Schema; } - createId = async()=>Math.max(...(await this._content.find({})).map(x=>x.id), 0) + 1; + async findInCache(): Promise { + const cacheKey = 'punishments'; + const cachedResult = await CacheServer.get(cacheKey); + let result; + if (cachedResult) { + try { + result = cachedResult; + } catch (error) { + console.error('Error parsing cached result:', error); + result = await this._content.find(); + CacheServer.set(cacheKey, result); + CacheServer.expiry(cacheKey, 15); + } + } else { + result = await this._content.find(); + CacheServer.set(cacheKey, result); + CacheServer.expiry(cacheKey, 15); + } + return result; + } + createId = async()=>Math.max(...(await this._content.find()).map(x=>x.id), 0) + 1; async makeModlogEntry(punishment:Punishment){ // Format data into an embed const channel = ['kick', 'ban'].includes(punishment.type) ? this.client.config.mainServer.channels.bankick_log : this.client.config.mainServer.channels.logs; diff --git a/src/models/tagSystem.ts b/src/models/tagSystem.ts index dff11e3..889e530 100644 --- a/src/models/tagSystem.ts +++ b/src/models/tagSystem.ts @@ -1,5 +1,6 @@ import TClient from '../client.js'; import mongoose from 'mongoose'; +import CacheServer from '../funcs/CacheServer.js'; const Schema = mongoose.model('tags', new mongoose.Schema({ _id: {type: String, required:true}, @@ -19,4 +20,32 @@ export default class tags extends Schema { this.client = client; this._content = Schema; } + async findInCache(): Promise { + const cacheKey = 'Tags'; + const cachedResult = await CacheServer.get(cacheKey); + let result; + if (cachedResult) { + try { + result = cachedResult; + } catch (error) { + console.error('Error parsing cached result:', error); + result = await this._content.find(); + CacheServer.set(cacheKey, result); + CacheServer.expiry(cacheKey, 240); + } + } else { + result = await this._content.find(); + CacheServer.set(cacheKey, result); + CacheServer.expiry(cacheKey, 240); + } + return result; + } + async updateCache(): Promise { + const cacheKey = 'Tags'; + CacheServer.delete(cacheKey); + const result = await this._content.find(); + CacheServer.set(cacheKey, result); + CacheServer.expiry(cacheKey, 10); + return result; + } } diff --git a/src/typings/interfaces.d.ts b/src/typings/interfaces.d.ts index 7903b21..d43204f 100644 --- a/src/typings/interfaces.d.ts +++ b/src/typings/interfaces.d.ts @@ -122,6 +122,7 @@ export interface Tokens { octokit: string mongodb_uri: string mongodb_uri_dev: string + redis_uri: string } export interface Config { embedColor: Discord.ColorResolvable, diff --git a/yarn.lock b/yarn.lock index 174314a..7c27723 100644 --- a/yarn.lock +++ b/yarn.lock @@ -360,6 +360,62 @@ __metadata: languageName: node linkType: hard +"@redis/bloom@npm:1.2.0": + version: 1.2.0 + resolution: "@redis/bloom@npm:1.2.0" + peerDependencies: + "@redis/client": ^1.0.0 + checksum: 8c214227287d6b278109098bca00afc601cf84f7da9c6c24f4fa7d3854b946170e5893aa86ed607ba017a4198231d570541c79931b98b6d50b262971022d1d6c + languageName: node + linkType: hard + +"@redis/client@npm:1.5.11": + version: 1.5.11 + resolution: "@redis/client@npm:1.5.11" + dependencies: + cluster-key-slot: 1.1.2 + generic-pool: 3.9.0 + yallist: 4.0.0 + checksum: 10f25a74f18b4e87299c11c014840895f387d217f1309a5208939e8bab8c95abecf2ca824f1cd0fe935b8972a18e0c4d6dd25640e742f4b30d38208515cf3a42 + languageName: node + linkType: hard + +"@redis/graph@npm:1.1.0": + version: 1.1.0 + resolution: "@redis/graph@npm:1.1.0" + peerDependencies: + "@redis/client": ^1.0.0 + checksum: d3df807108a42929ed65269c691fe6ab7eda55de91318f02a22b2d637c1bfef8817fccd17025904f5a0be8cf1cea5941334ec9f10719336da5d8f1c54cd4997e + languageName: node + linkType: hard + +"@redis/json@npm:1.0.6": + version: 1.0.6 + resolution: "@redis/json@npm:1.0.6" + peerDependencies: + "@redis/client": ^1.0.0 + checksum: 9fda29abc339c72593f34a23f8023b715c1f8f3d73f7c59889af02f25589bac2ad57073ad08d0b8da42cd8c258665a7b38d39e761e92945cc27aca651c8a93a5 + languageName: node + linkType: hard + +"@redis/search@npm:1.1.5": + version: 1.1.5 + resolution: "@redis/search@npm:1.1.5" + peerDependencies: + "@redis/client": ^1.0.0 + checksum: f81771a712957334029f75b4a68f54b0c78abe17d78546f6da9cd5c7e8f768c69f2f9d3c25840053dbe3c1931038f924403fc3f1bb359ac3defdae85e86fd26b + languageName: node + linkType: hard + +"@redis/time-series@npm:1.0.5": + version: 1.0.5 + resolution: "@redis/time-series@npm:1.0.5" + peerDependencies: + "@redis/client": ^1.0.0 + checksum: 6bbdb0b793dcbd13518aa60a09a980f953554e4c745bfacc1611baa8098f360e0378e8ee6b7faf600a67f1de83f4b68bbec6f95a0740faee6164c14be3a30752 + languageName: node + linkType: hard + "@sapphire/async-queue@npm:^1.5.0": version: 1.5.0 resolution: "@sapphire/async-queue@npm:1.5.0" @@ -648,6 +704,13 @@ __metadata: languageName: node linkType: hard +"cluster-key-slot@npm:1.1.2": + version: 1.1.2 + resolution: "cluster-key-slot@npm:1.1.2" + checksum: be0ad2d262502adc998597e83f9ded1b80f827f0452127c5a37b22dfca36bab8edf393f7b25bb626006fb9fb2436106939ede6d2d6ecf4229b96a47f27edd681 + languageName: node + linkType: hard + "color-convert@npm:^2.0.1": version: 2.0.1 resolution: "color-convert@npm:2.0.1" @@ -736,6 +799,7 @@ __metadata: mongoose: 7.5.3 ms: 2.1.3 prism-media: 1.3.5 + redis: 4.6.10 systeminformation: 5.21.9 typescript: 5.2.2 xml-js: 1.6.11 @@ -1070,6 +1134,13 @@ __metadata: languageName: node linkType: hard +"generic-pool@npm:3.9.0": + version: 3.9.0 + resolution: "generic-pool@npm:3.9.0" + checksum: 3d89e9b2018d2e3bbf44fec78c76b2b7d56d6a484237aa9daf6ff6eedb14b0899dadd703b5d810219baab2eb28e5128fb18b29e91e602deb2eccac14492d8ca8 + languageName: node + linkType: hard + "genius-lyrics@npm:^4.4.6": version: 4.4.6 resolution: "genius-lyrics@npm:4.4.6" @@ -1906,6 +1977,20 @@ __metadata: languageName: node linkType: hard +"redis@npm:4.6.10": + version: 4.6.10 + resolution: "redis@npm:4.6.10" + dependencies: + "@redis/bloom": 1.2.0 + "@redis/client": 1.5.11 + "@redis/graph": 1.1.0 + "@redis/json": 1.0.6 + "@redis/search": 1.1.5 + "@redis/time-series": 1.0.5 + checksum: eae6e10f6ec8d5c6d6dea04a1ee6f6497319113e07dbf272a2b4b3c461c34d6fda152791f443c93c538ad6477741a6b157886b60d06f5fce2abbf403e6568a2f + languageName: node + linkType: hard + "retry@npm:^0.12.0": version: 0.12.0 resolution: "retry@npm:0.12.0" @@ -2440,7 +2525,7 @@ __metadata: languageName: node linkType: hard -"yallist@npm:^4.0.0": +"yallist@npm:4.0.0, yallist@npm:^4.0.0": version: 4.0.0 resolution: "yallist@npm:4.0.0" checksum: 343617202af32df2a15a3be36a5a8c0c8545208f3d3dfbc6bb7c3e3b7e8c6f8e7485432e4f3b88da3031a6e20afa7c711eded32ddfb122896ac5d914e75848d5