feat(page.note): add delay and retry to embedded note loading

This commit is contained in:
Outvi V 2025-05-31 00:40:13 +08:00
parent 79ff245aa4
commit 85bc401e47
2 changed files with 46 additions and 5 deletions

View file

@ -11,7 +11,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import { onMounted, onUnmounted, ref } from 'vue';
import * as Misskey from 'misskey-js';
import MkNote from '@/components/MkNote.vue';
import MkNoteDetailed from '@/components/MkNoteDetailed.vue';
@ -20,16 +20,57 @@ import { misskeyApi } from '@/utility/misskey-api.js';
const props = defineProps<{
block: Misskey.entities.PageBlock,
page: Misskey.entities.Page,
index: number;
}>();
const note = ref<Misskey.entities.Note | null>(null);
let timeoutId = null;
async function sleep(ms: number): Promise<void> {
return new Promise((resolve) => {
setTimeout(() => {
resolve()
}, ms);
});
}
async function retryOnThrottle<T>(f: ()=>Promise<T>, retryCount: number = 5): Promise<T> {
let lastResult: T = undefined!;
const r = Math.random();
for(let i=0; i<retryCount; i++) {
const [ok, resultOrError] = await f()
.then(result => [true, result])
.catch(err => [false, err]);
lastResult = resultOrError;
if (ok) {
break;
}
// RATE_LIMIT_EXCEEDED
if (resultOrError?.id === "d5826d14-3982-4d2e-8011-b9e9f02499ef") {
await sleep(resultOrError?.info?.fullResetMs ?? 1000);
continue;
}
throw resultOrError;
}
return lastResult;
}
onMounted(() => {
if (props.block.note == null) return;
misskeyApi('notes/show', { noteId: props.block.note })
.then(result => {
timeoutId = setTimeout(() => {
retryOnThrottle(() => misskeyApi('notes/show', { noteId: props.block.note })).then(result => {
note.value = result;
});
}, 500 * props.index); // rate limit is 2 reqs per sec
});
onUnmounted(() => {
if (timeoutId !== null) clearTimeout(timeoutId);
});
</script>

View file

@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<div :class="{ [$style.center]: page.alignCenter, [$style.serif]: page.font === 'serif' }" class="_gaps">
<XBlock v-for="child in page.content" :key="child.id" :page="page" :block="child" :h="2"/>
<XBlock v-for="(child, index) in page.content" :key="child.id" :index="index" :page="page" :block="child" :h="2"/>
</div>
</template>