summaryrefslogtreecommitdiff
path: root/packages/backend/src/misc/distributed-lock.ts
diff options
context:
space:
mode:
authorrenovate[bot] <29139614+renovate[bot]@users.noreply.github.com>2025-11-30 09:58:06 +0900
committerGitHub <noreply@github.com>2025-11-30 09:58:06 +0900
commit0455187a689b45575121851e6998a3d13615567c (patch)
tree37c179d0bc9e9385673d922247c4dd826f4f0850 /packages/backend/src/misc/distributed-lock.ts
parentBump version to 2025.11.2-alpha.0 (diff)
downloadmisskey-0455187a689b45575121851e6998a3d13615567c.tar.gz
misskey-0455187a689b45575121851e6998a3d13615567c.tar.bz2
misskey-0455187a689b45575121851e6998a3d13615567c.zip
fix(deps): update [backend] update dependencies (major) (#16099)
* fix(deps): update [backend] update dependencies * update approve builds * update minimum node version for testing * remove types/bcryptjs * fix(backend): remove removed type previously exported from file-type * migrate webauthnservice * Update Changelog * update deps (MisskeyIO#889) - メンテナンスされないredis-lockを自前実装に変更 - 既にロックされている場合のリトライ間隔を調整 * use main redis for lock * spdx * tweak max retries * [ci skip] dedupe * attempt to fix test * attempt to fix test * Revert "attempt to fix test" This reverts commit c508318627e4ffab030e1acf5182f58cc2eb51d8. * temporarily roll back simonjs/fake-timers to v11.3.1 * Revert "temporarily roll back simonjs/fake-timers to v11.3.1" This reverts commit 54f1fc3d7917089e05b20fc5b86435e3f5e5b040. * migrate sinonjs/fake-timers * update deps / migrate jest 30 * fix test * fix: update node.js min version to 20.18.1 * fix: rollback nsfwjs to 4.2.0 * fix * attempt to fix test * attempt to fix test * attempt to fix test * attempt to fix test * revert jest 30 related changes * update deps * fix test * fix: rollback nsfwjs to 4.2.0 * fix: rollback sharp to 0.33 * update deps * fix: rollback sharp-read-bmp to 1.2.0 * fix: rollback nsfwjs to 4.2.0 * recreate lockfile * update deps * fix: rollback sharp-read-bmp to 1.2.0 * fix: rollback jsdom, parse5 * fix: rollback jsdom types * fix [ci skip] * run pnpm dedupe * update deps * run pnpm dedupe [ci skip] * Update Changelog [ci skip] --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: kakkokari-gtyih <67428053+kakkokari-gtyih@users.noreply.github.com> Co-authored-by: あわわわとーにゅ <17376330+u1-liquid@users.noreply.github.com> Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
Diffstat (limited to 'packages/backend/src/misc/distributed-lock.ts')
-rw-r--r--packages/backend/src/misc/distributed-lock.ts49
1 files changed, 49 insertions, 0 deletions
diff --git a/packages/backend/src/misc/distributed-lock.ts b/packages/backend/src/misc/distributed-lock.ts
new file mode 100644
index 0000000000..93bd741f62
--- /dev/null
+++ b/packages/backend/src/misc/distributed-lock.ts
@@ -0,0 +1,49 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and misskey-project
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+import * as Redis from 'ioredis';
+
+export async function acquireDistributedLock(
+ redis: Redis.Redis,
+ name: string,
+ timeout: number,
+ maxRetries: number,
+ retryInterval: number,
+): Promise<() => Promise<void>> {
+ const lockKey = `lock:${name}`;
+ const identifier = Math.random().toString(36).slice(2);
+
+ let retries = 0;
+ while (retries < maxRetries) {
+ const result = await redis.set(lockKey, identifier, 'PX', timeout, 'NX');
+ if (result === 'OK') {
+ return async () => {
+ const currentIdentifier = await redis.get(lockKey);
+ if (currentIdentifier === identifier) {
+ await redis.del(lockKey);
+ }
+ };
+ }
+
+ await new Promise(resolve => setTimeout(resolve, retryInterval));
+ retries++;
+ }
+
+ throw new Error(`Failed to acquire lock ${name}`);
+}
+
+export function acquireApObjectLock(
+ redis: Redis.Redis,
+ uri: string,
+): Promise<() => Promise<void>> {
+ return acquireDistributedLock(redis, `ap-object:${uri}`, 30 * 1000, 50, 100);
+}
+
+export function acquireChartInsertLock(
+ redis: Redis.Redis,
+ name: string,
+): Promise<() => Promise<void>> {
+ return acquireDistributedLock(redis, `chart-insert:${name}`, 30 * 1000, 50, 500);
+}