From 49fd8a5dc9b56d471cfe5f1661639777d7d54348 Mon Sep 17 00:00:00 2001 From: Lim Chee Aun Date: Fri, 22 Dec 2023 09:54:50 +0800 Subject: [PATCH] Further rate limit this threadify calls Every post calls threadify and clogs the RAF --- src/utils/ratelimit.js | 26 ++++++++++++++++++++++++++ src/utils/states.js | 6 ++++-- 2 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 src/utils/ratelimit.js diff --git a/src/utils/ratelimit.js b/src/utils/ratelimit.js new file mode 100644 index 0000000..6b49cd3 --- /dev/null +++ b/src/utils/ratelimit.js @@ -0,0 +1,26 @@ +// Rate limit repeated function calls and queue them to set interval +export default function rateLimit(fn, interval) { + let queue = []; + let isRunning = false; + + function executeNext() { + if (queue.length === 0) { + isRunning = false; + return; + } + + const nextFn = queue.shift(); + nextFn(); + setTimeout(executeNext, interval); + } + + return function (...args) { + const callFn = () => fn.apply(this, args); + queue.push(callFn); + + if (!isRunning) { + isRunning = true; + setTimeout(executeNext, interval); + } + }; +} diff --git a/src/utils/states.js b/src/utils/states.js index 6ab72c9..f71784a 100644 --- a/src/utils/states.js +++ b/src/utils/states.js @@ -3,6 +3,7 @@ import { subscribeKey } from 'valtio/utils'; import { api } from './api'; import pmem from './pmem'; +import rateLimit from './ratelimit'; import store from './store'; const states = proxy({ @@ -187,7 +188,7 @@ export function saveStatus(status, instance, opts) { } } -export function threadifyStatus(status, propInstance) { +function _threadifyStatus(status, propInstance) { const { masto, instance } = api({ instance: propInstance }); // Return all statuses in the thread, via inReplyToId, if inReplyToAccountId === account.id let fetchIndex = 0; @@ -204,7 +205,7 @@ export function threadifyStatus(status, propInstance) { let prevStatus = states.statuses[key]; if (!prevStatus) { if (fetchIndex++ > 3) throw 'Too many fetches for thread'; // Some people revive old threads - await new Promise((r) => setTimeout(r, 500 * fetchIndex)); // Be nice to rate limits + await new Promise((r) => setTimeout(r, 300 * fetchIndex)); // Be nice to rate limits // prevStatus = await masto.v1.statuses.$.select(inReplyToId).fetch(); prevStatus = await fetchStatus(inReplyToId, masto); saveStatus(prevStatus, instance, { skipThreading: true }); @@ -226,6 +227,7 @@ export function threadifyStatus(status, propInstance) { console.error(e, status); }); } +export const threadifyStatus = rateLimit(_threadifyStatus, 300); const fetchStatus = pmem((statusID, masto) => { return masto.v1.statuses.$select(statusID).fetch();