From 63c193f9fc14e09a452eb66a8f7b73a6c97178a7 Mon Sep 17 00:00:00 2001 From: ThatOneCalculator Date: Sun, 2 Jul 2023 10:10:25 -0700 Subject: [PATCH] Revert "Merge pull request '[PR]: fix: use redis-based mutex to prevent memory leak' (#10389) from nmkj/calckey:fix-cache-leak into develop" This reverts commit 224b1d585bb1cb95531a9213cf4a69fc2f049e7d, reversing changes made to b5907fb86db2b9eacea633bb5d69547982326afa. --- packages/backend/package.json | 1 + packages/backend/src/misc/emoji-meta.ts | 36 ++++------ pnpm-lock.yaml | 94 ++++++------------------- 3 files changed, 36 insertions(+), 95 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index fd5b2c3b3..b584a5691 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -43,6 +43,7 @@ "ajv": "8.12.0", "archiver": "5.3.1", "argon2": "^0.30.3", + "async-mutex": "^0.4.0", "autobind-decorator": "2.4.0", "autolinker": "4.0.0", "autwh": "0.1.0", diff --git a/packages/backend/src/misc/emoji-meta.ts b/packages/backend/src/misc/emoji-meta.ts index 3bcc4262b..fd9d9baa5 100644 --- a/packages/backend/src/misc/emoji-meta.ts +++ b/packages/backend/src/misc/emoji-meta.ts @@ -1,48 +1,42 @@ import probeImageSize from "probe-image-size"; -import { Mutex } from "redis-semaphore"; +import { Mutex, withTimeout } from "async-mutex"; import { FILE_TYPE_BROWSERSAFE } from "@/const.js"; import Logger from "@/services/logger.js"; -import { redisClient } from "@/db/redis.js"; +import { Cache } from "./cache.js"; export type Size = { width: number; height: number; }; -const logger = new Logger("emoji"); +const cache = new Cache(1000 * 60 * 10); // once every 10 minutes for the same url +const mutex = withTimeout(new Mutex(), 1000); export async function getEmojiSize(url: string): Promise { - let attempted = true; + const logger = new Logger("emoji"); - const lock = new Mutex(redisClient, "getEmojiSize"); - await lock.acquire(); - try { - const key = `getEmojiSize:${url}`; - attempted = (await redisClient.get(key)) !== null; + await mutex.runExclusive(() => { + const attempted = cache.get(url); if (!attempted) { - await redisClient.set(key, "done", "EX", 60 * 10); + cache.set(url, true); + } else { + logger.warn(`Attempt limit exceeded: ${url}`); + throw new Error("Too many attempts"); } - } finally { - await lock.release(); - } - - if (attempted) { - logger.warn(`Attempt limit exceeded: ${url}`); - throw new Error("attempt limit exceeded"); - } + }); try { - logger.debug(`Retrieving emoji size from ${url}`); + logger.info(`Retrieving emoji size from ${url}`); const { width, height, mime } = await probeImageSize(url, { timeout: 5000, }); if (!(mime.startsWith("image/") && FILE_TYPE_BROWSERSAFE.includes(mime))) { - throw new Error("unsupported image type"); + throw new Error("Unsupported image type"); } return { width, height }; } catch (e) { - throw new Error(`unable to retrieve metadata: ${e}`); + throw new Error(`Unable to retrieve metadata: ${e}`); } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c7c0089ee..1002a6f95 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -132,6 +132,9 @@ importers: argon2: specifier: ^0.30.3 version: 0.30.3 + async-mutex: + specifier: ^0.4.0 + version: 0.4.0 autobind-decorator: specifier: 2.4.0 version: 2.4.0 @@ -598,7 +601,7 @@ importers: version: 5.1.3 webpack: specifier: ^5.85.1 - version: 5.85.1(@swc/core@1.3.62) + version: 5.85.1(@swc/core@1.3.62)(webpack-cli@5.1.3) ws: specifier: 8.13.0 version: 8.13.0 @@ -4493,6 +4496,12 @@ packages: stream-exhaust: 1.0.2 dev: true + /async-mutex@0.4.0: + resolution: {integrity: sha512-eJFZ1YhRR8UN8eBLoNzcDPcy/jqjsg6I1AP+KvWQX80BqOSW1oJPJXDylPUEeMr2ZQvHgnQ//Lp6f3RQ1zI7HA==} + dependencies: + tslib: 2.6.0 + dev: false + /async-settle@1.0.0: resolution: {integrity: sha512-VPXfB4Vk49z1LHHodrEQ6Xf7W4gg1w0dAPROHngx7qgDjqmIQ+fXmwgGXTW/ITLai0YLSvWepJOP9EVpMnEAcw==} engines: {node: '>= 0.10'} @@ -4637,7 +4646,7 @@ packages: /axios@0.24.0: resolution: {integrity: sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==} dependencies: - follow-redirects: 1.15.2 + follow-redirects: 1.15.2(debug@4.3.4) transitivePeerDependencies: - debug dev: false @@ -4653,7 +4662,7 @@ packages: /axios@1.2.2: resolution: {integrity: sha512-bz/J4gS2S3I7mpN/YZfGFTqhXTYzRho8Ay38w2otuuDR322KzFIWm/4W2K6gIwvWaws5n+mnb7D1lN9uD+QH6Q==} dependencies: - follow-redirects: 1.15.2 + follow-redirects: 1.15.2(debug@4.3.4) form-data: 4.0.0 proxy-from-env: 1.1.0 transitivePeerDependencies: @@ -4663,7 +4672,7 @@ packages: /axios@1.4.0: resolution: {integrity: sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==} dependencies: - follow-redirects: 1.15.2 + follow-redirects: 1.15.2(debug@4.3.4) form-data: 4.0.0 proxy-from-env: 1.1.0 transitivePeerDependencies: @@ -6279,17 +6288,6 @@ packages: dependencies: ms: 2.0.0 - /debug@3.2.7: - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.3 - dev: false - /debug@3.2.7(supports-color@8.1.1): resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: @@ -6300,7 +6298,6 @@ packages: dependencies: ms: 2.1.3 supports-color: 8.1.1 - dev: true /debug@4.3.3: resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==} @@ -7538,16 +7535,6 @@ packages: tabbable: 6.2.0 dev: true - /follow-redirects@1.15.2: - resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - dev: false - /follow-redirects@1.15.2(debug@4.3.4): resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} engines: {node: '>=4.0'} @@ -7558,7 +7545,6 @@ packages: optional: true dependencies: debug: 4.3.4(supports-color@8.1.1) - dev: true /for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} @@ -8469,7 +8455,7 @@ packages: engines: {node: '>= 4.5.0'} dependencies: agent-base: 4.3.0 - debug: 3.2.7 + debug: 3.2.7(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: false @@ -9868,7 +9854,7 @@ packages: json5: 2.2.3 loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.85.1(@swc/core@1.3.62) + webpack: 5.85.1(@swc/core@1.3.62)(webpack-cli@5.1.3) dev: true /json5@2.2.3: @@ -10111,7 +10097,7 @@ packages: resolution: {integrity: sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ==} engines: {node: '>= 7.6.0'} dependencies: - debug: 3.2.7 + debug: 3.2.7(supports-color@8.1.1) koa-send: 5.0.1 transitivePeerDependencies: - supports-color @@ -11105,7 +11091,7 @@ packages: engines: {node: '>= 4.4.x'} hasBin: true dependencies: - debug: 3.2.7 + debug: 3.2.7(supports-color@8.1.1) iconv-lite: 0.4.24 sax: 1.2.4 transitivePeerDependencies: @@ -14011,7 +13997,7 @@ packages: webpack: '>=2' dependencies: '@swc/core': 1.3.62 - webpack: 5.85.1(@swc/core@1.3.62) + webpack: 5.85.1(@swc/core@1.3.62)(webpack-cli@5.1.3) dev: true /swiper@9.3.2: @@ -14132,7 +14118,7 @@ packages: schema-utils: 3.3.0 serialize-javascript: 6.0.1 terser: 5.18.2 - webpack: 5.85.1(@swc/core@1.3.62) + webpack: 5.85.1(@swc/core@1.3.62)(webpack-cli@5.1.3) dev: true /terser@5.18.2: @@ -14432,7 +14418,7 @@ packages: micromatch: 4.0.5 semver: 7.5.1 typescript: 5.1.3 - webpack: 5.85.1(@swc/core@1.3.62) + webpack: 5.85.1(@swc/core@1.3.62)(webpack-cli@5.1.3) dev: true /ts-node@10.4.0(@swc/core@1.3.62)(@types/node@20.3.1)(typescript@5.1.3): @@ -15266,46 +15252,6 @@ packages: engines: {node: '>=10.13.0'} dev: true - /webpack@5.85.1(@swc/core@1.3.62): - resolution: {integrity: sha512-xTb7MRf4LY8Z5rzn7aIx4TDrwYJrjcHnIfU1TqtyZOoObyuGSpAUwIvVuqq5wPnv7WEgQr8UvO1q/dgoGG4HjA==} - engines: {node: '>=10.13.0'} - hasBin: true - peerDependencies: - webpack-cli: '*' - peerDependenciesMeta: - webpack-cli: - optional: true - dependencies: - '@types/eslint-scope': 3.7.4 - '@types/estree': 1.0.1 - '@webassemblyjs/ast': 1.11.6 - '@webassemblyjs/wasm-edit': 1.11.6 - '@webassemblyjs/wasm-parser': 1.11.6 - acorn: 8.9.0 - acorn-import-assertions: 1.9.0(acorn@8.9.0) - browserslist: 4.21.9 - chrome-trace-event: 1.0.3 - enhanced-resolve: 5.15.0 - es-module-lexer: 1.3.0 - eslint-scope: 5.1.1 - events: 3.3.0 - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.0 - mime-types: 2.1.35 - neo-async: 2.6.2 - schema-utils: 3.3.0 - tapable: 2.2.1 - terser-webpack-plugin: 5.3.9(@swc/core@1.3.62)(webpack@5.85.1) - watchpack: 2.4.0 - webpack-sources: 3.2.3 - transitivePeerDependencies: - - '@swc/core' - - esbuild - - uglify-js - dev: true - /webpack@5.85.1(@swc/core@1.3.62)(webpack-cli@5.1.3): resolution: {integrity: sha512-xTb7MRf4LY8Z5rzn7aIx4TDrwYJrjcHnIfU1TqtyZOoObyuGSpAUwIvVuqq5wPnv7WEgQr8UvO1q/dgoGG4HjA==} engines: {node: '>=10.13.0'}