diff options
| author | syuilo <4439005+syuilo@users.noreply.github.com> | 2025-04-19 14:00:38 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-04-19 14:00:38 +0900 |
| commit | 7b38806413b84bd20070f3c81b899e5b890b1a8b (patch) | |
| tree | 2385b32546d410ff2e5e208793f7ad82ad6623ab /packages/frontend/src/pages/admin/queue.chart.vue | |
| parent | fix(storybook): implement missing stories (#15862) (diff) | |
| download | misskey-7b38806413b84bd20070f3c81b899e5b890b1a8b.tar.gz misskey-7b38806413b84bd20070f3c81b899e5b890b1a8b.tar.bz2 misskey-7b38806413b84bd20070f3c81b899e5b890b1a8b.zip | |
feat: Job queue inspector (#15856)
* wip
* wip
* Update job-queue.vue
* wip
* wip
* Update job-queue.vue
* wip
* Update job-queue.vue
* wip
* Update QueueService.ts
* Update QueueService.ts
* Update QueueService.ts
* Update job-queue.vue
* wip
* wip
* wip
* Update job-queue.vue
* wip
* Update MkTl.vue
* wip
* Update index.vue
* wip
* wip
* Update MkTl.vue
* 🎨
* jobs search
* wip
* Update job-queue.vue
* wip
* wip
* Update job-queue.vue
* Update job-queue.vue
* Update job-queue.vue
* Update job-queue.vue
* wip
* Update job-queue.job.vue
* wip
* wip
* wip
* Update MkCode.vue
* wip
* Update job-queue.job.vue
* wip
* Update job-queue.job.vue
* Update misskey-js.api.md
* Update CHANGELOG.md
* Update job-queue.job.vue
Diffstat (limited to 'packages/frontend/src/pages/admin/queue.chart.vue')
| -rw-r--r-- | packages/frontend/src/pages/admin/queue.chart.vue | 160 |
1 files changed, 0 insertions, 160 deletions
diff --git a/packages/frontend/src/pages/admin/queue.chart.vue b/packages/frontend/src/pages/admin/queue.chart.vue deleted file mode 100644 index 1ba02d6e0e..0000000000 --- a/packages/frontend/src/pages/admin/queue.chart.vue +++ /dev/null @@ -1,160 +0,0 @@ -<!-- -SPDX-FileCopyrightText: syuilo and misskey-project -SPDX-License-Identifier: AGPL-3.0-only ---> - -<template> -<div class="_gaps"> - <div :class="$style.status"> - <div :class="$style.statusItem" class="_panel"><div :class="$style.statusLabel">Process</div>{{ number(activeSincePrevTick) }}</div> - <div :class="$style.statusItem" class="_panel"><div :class="$style.statusLabel">Active</div>{{ number(active) }}</div> - <div :class="$style.statusItem" class="_panel"><div :class="$style.statusLabel">Waiting</div>{{ number(waiting) }}</div> - <div :class="$style.statusItem" class="_panel"><div :class="$style.statusLabel">Delayed</div>{{ number(delayed) }}</div> - </div> - <div :class="$style.charts"> - <div :class="$style.chart"> - <div :class="$style.chartTitle">Process</div> - <XChart ref="chartProcess" type="process"/> - </div> - <div :class="$style.chart"> - <div :class="$style.chartTitle">Active</div> - <XChart ref="chartActive" type="active"/> - </div> - <div :class="$style.chart"> - <div :class="$style.chartTitle">Delayed</div> - <XChart ref="chartDelayed" type="delayed"/> - </div> - <div :class="$style.chart"> - <div :class="$style.chartTitle">Waiting</div> - <XChart ref="chartWaiting" type="waiting"/> - </div> - </div> - <MkFolder :defaultOpen="true" :max-height="250"> - <template #icon><i class="ti ti-alert-triangle"></i></template> - <template #label>Errored instances</template> - <template #suffix>({{ number(jobs.reduce((a, b) => a + b[1], 0)) }} jobs)</template> - - <div> - <div v-if="jobs.length > 0"> - <div v-for="job in jobs" :key="job[0]"> - <MkA :to="`/instance-info/${job[0]}`" behavior="window">{{ job[0] }}</MkA> - <span style="margin-left: 8px; opacity: 0.7;">({{ number(job[1]) }} jobs)</span> - </div> - </div> - <span v-else style="opacity: 0.5;">{{ i18n.ts.noJobs }}</span> - </div> - </MkFolder> -</div> -</template> - -<script lang="ts" setup> -import { markRaw, onMounted, onUnmounted, ref, useTemplateRef } from 'vue'; -import * as Misskey from 'misskey-js'; -import XChart from './queue.chart.chart.vue'; -import type { ApQueueDomain } from '@/pages/admin/queue.vue'; -import number from '@/filters/number.js'; -import { misskeyApi } from '@/utility/misskey-api.js'; -import { useStream } from '@/stream.js'; -import { i18n } from '@/i18n.js'; -import MkFolder from '@/components/MkFolder.vue'; - -const connection = markRaw(useStream().useChannel('queueStats')); - -const activeSincePrevTick = ref(0); -const active = ref(0); -const delayed = ref(0); -const waiting = ref(0); -const jobs = ref<Misskey.Endpoints[`admin/queue/${ApQueueDomain}-delayed`]['res']>([]); -const chartProcess = useTemplateRef('chartProcess'); -const chartActive = useTemplateRef('chartActive'); -const chartDelayed = useTemplateRef('chartDelayed'); -const chartWaiting = useTemplateRef('chartWaiting'); - -const props = defineProps<{ - domain: ApQueueDomain; -}>(); - -function onStats(stats: Misskey.entities.QueueStats) { - activeSincePrevTick.value = stats[props.domain].activeSincePrevTick; - active.value = stats[props.domain].active; - delayed.value = stats[props.domain].delayed; - waiting.value = stats[props.domain].waiting; - - chartProcess.value.pushData(stats[props.domain].activeSincePrevTick); - chartActive.value.pushData(stats[props.domain].active); - chartDelayed.value.pushData(stats[props.domain].delayed); - chartWaiting.value.pushData(stats[props.domain].waiting); -} - -function onStatsLog(statsLog: Misskey.entities.QueueStatsLog) { - const dataProcess: Misskey.entities.QueueStats[ApQueueDomain]['activeSincePrevTick'][] = []; - const dataActive: Misskey.entities.QueueStats[ApQueueDomain]['active'][] = []; - const dataDelayed: Misskey.entities.QueueStats[ApQueueDomain]['delayed'][] = []; - const dataWaiting: Misskey.entities.QueueStats[ApQueueDomain]['waiting'][] = []; - - for (const stats of [...statsLog].reverse()) { - dataProcess.push(stats[props.domain].activeSincePrevTick); - dataActive.push(stats[props.domain].active); - dataDelayed.push(stats[props.domain].delayed); - dataWaiting.push(stats[props.domain].waiting); - } - - chartProcess.value.setData(dataProcess); - chartActive.value.setData(dataActive); - chartDelayed.value.setData(dataDelayed); - chartWaiting.value.setData(dataWaiting); -} - -onMounted(() => { - misskeyApi(`admin/queue/${props.domain}-delayed`).then(result => { - jobs.value = result; - }); - - connection.on('stats', onStats); - connection.on('statsLog', onStatsLog); - connection.send('requestLog', { - id: Math.random().toString().substring(2, 10), - length: 200, - }); -}); - -onUnmounted(() => { - connection.off('stats', onStats); - connection.off('statsLog', onStatsLog); - connection.dispose(); -}); -</script> - -<style lang="scss" module> -.charts { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 10px; -} - -.chart { - min-width: 0; - padding: 16px; - background: var(--MI_THEME-panel); - border-radius: var(--MI-radius); -} - -.chartTitle { - margin-bottom: 8px; -} - -.status { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); - grid-gap: 10px; -} - -.statusItem { - padding: 12px 16px; -} - -.statusLabel { - font-size: 80%; - opacity: 0.6; -} -</style> |