enhance: コントロールパネルでジョブキューをクリアできるように
This commit is contained in:
parent
f2aeafaddb
commit
eda2f587a3
|
@ -7,6 +7,7 @@
|
||||||
- Feat: チャットウィジェットを追加
|
- Feat: チャットウィジェットを追加
|
||||||
- Feat: デッキにチャットカラムを追加
|
- Feat: デッキにチャットカラムを追加
|
||||||
- Enhance: Unicode絵文字をslugから入力する際に`:ok:`のように最後の`:`を入力したあとにUnicode絵文字に変換できるように
|
- Enhance: Unicode絵文字をslugから入力する際に`:ok:`のように最後の`:`を入力したあとにUnicode絵文字に変換できるように
|
||||||
|
- Enhance: コントロールパネルでジョブキューをクリアできるように
|
||||||
- Enhance: テーマでページヘッダーの色を変更できるように
|
- Enhance: テーマでページヘッダーの色を変更できるように
|
||||||
- Enhance: デザインのブラッシュアップ
|
- Enhance: デザインのブラッシュアップ
|
||||||
- Fix: ログアウトした際に処理が終了しない問題を修正
|
- Fix: ログアウトした際に処理が終了しない問題を修正
|
||||||
|
|
|
@ -38,6 +38,18 @@ import type {
|
||||||
import type httpSignature from '@peertube/http-signature';
|
import type httpSignature from '@peertube/http-signature';
|
||||||
import type * as Bull from 'bullmq';
|
import type * as Bull from 'bullmq';
|
||||||
|
|
||||||
|
export const QUEUE_TYPES = [
|
||||||
|
'system',
|
||||||
|
'endedPollNotification',
|
||||||
|
'deliver',
|
||||||
|
'inbox',
|
||||||
|
'db',
|
||||||
|
'relationship',
|
||||||
|
'objectStorage',
|
||||||
|
'userWebhookDeliver',
|
||||||
|
'systemWebhookDeliver',
|
||||||
|
] as const;
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class QueueService {
|
export class QueueService {
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -529,15 +541,35 @@ export class QueueService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public destroy() {
|
private getQueue(type: typeof QUEUE_TYPES[number]) {
|
||||||
this.deliverQueue.once('cleaned', (jobs, status) => {
|
switch (type) {
|
||||||
//deliverLogger.succ(`Cleaned ${jobs.length} ${status} jobs`);
|
case 'system': return this.systemQueue;
|
||||||
});
|
case 'endedPollNotification': return this.endedPollNotificationQueue;
|
||||||
this.deliverQueue.clean(0, 0, 'delayed');
|
case 'deliver': return this.deliverQueue;
|
||||||
|
case 'inbox': return this.inboxQueue;
|
||||||
|
case 'db': return this.dbQueue;
|
||||||
|
case 'relationship': return this.relationshipQueue;
|
||||||
|
case 'objectStorage': return this.objectStorageQueue;
|
||||||
|
case 'userWebhookDeliver': return this.userWebhookDeliverQueue;
|
||||||
|
case 'systemWebhookDeliver': return this.systemWebhookDeliverQueue;
|
||||||
|
default: throw new Error(`Unrecognized queue type: ${type}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.inboxQueue.once('cleaned', (jobs, status) => {
|
@bindThis
|
||||||
//inboxLogger.succ(`Cleaned ${jobs.length} ${status} jobs`);
|
public clearQueue(queueType: typeof QUEUE_TYPES[number], state: '*' | 'completed' | 'wait' | 'active' | 'paused' | 'prioritized' | 'delayed' | 'failed') {
|
||||||
});
|
const queue = this.getQueue(queueType);
|
||||||
this.inboxQueue.clean(0, 0, 'delayed');
|
|
||||||
|
if (state === '*') {
|
||||||
|
queue.clean(0, 0, 'completed');
|
||||||
|
queue.clean(0, 0, 'wait');
|
||||||
|
queue.clean(0, 0, 'active');
|
||||||
|
queue.clean(0, 0, 'paused');
|
||||||
|
queue.clean(0, 0, 'prioritized');
|
||||||
|
queue.clean(0, 0, 'delayed');
|
||||||
|
queue.clean(0, 0, 'failed');
|
||||||
|
} else {
|
||||||
|
queue.clean(0, 0, state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||||
import { ModerationLogService } from '@/core/ModerationLogService.js';
|
import { ModerationLogService } from '@/core/ModerationLogService.js';
|
||||||
import { QueueService } from '@/core/QueueService.js';
|
import { QUEUE_TYPES, QueueService } from '@/core/QueueService.js';
|
||||||
|
|
||||||
export const meta = {
|
export const meta = {
|
||||||
tags: ['admin'],
|
tags: ['admin'],
|
||||||
|
@ -18,8 +18,11 @@ export const meta = {
|
||||||
|
|
||||||
export const paramDef = {
|
export const paramDef = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {},
|
properties: {
|
||||||
required: [],
|
type: { type: 'string', enum: QUEUE_TYPES },
|
||||||
|
state: { type: 'string', enum: ['*', 'wait', 'delayed'] },
|
||||||
|
},
|
||||||
|
required: ['type', 'state'],
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -29,7 +32,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
private queueService: QueueService,
|
private queueService: QueueService,
|
||||||
) {
|
) {
|
||||||
super(meta, paramDef, async (ps, me) => {
|
super(meta, paramDef, async (ps, me) => {
|
||||||
this.queueService.destroy();
|
this.queueService.clearQueue(ps.type, ps.state);
|
||||||
|
|
||||||
this.moderationLogService.log(me, 'clearQueue');
|
this.moderationLogService.log(me, 'clearQueue');
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,14 +10,16 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<XQueue v-if="tab === 'deliver'" domain="deliver"/>
|
<XQueue v-if="tab === 'deliver'" domain="deliver"/>
|
||||||
<XQueue v-else-if="tab === 'inbox'" domain="inbox"/>
|
<XQueue v-else-if="tab === 'inbox'" domain="inbox"/>
|
||||||
<br>
|
<br>
|
||||||
<MkButton @click="promoteAllQueues"><i class="ti ti-reload"></i> {{ i18n.ts.retryAllQueuesNow }}</MkButton>
|
<div class="_buttons">
|
||||||
|
<MkButton @click="promoteAllQueues"><i class="ti ti-reload"></i> {{ i18n.ts.retryAllQueuesNow }}</MkButton>
|
||||||
|
<MkButton danger @click="clear"><i class="ti ti-trash"></i> {{ i18n.ts.clearQueue }}</MkButton>
|
||||||
|
</div>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
</MkStickyContainer>
|
</MkStickyContainer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
import * as config from '@@/js/config.js';
|
|
||||||
import XQueue from './queue.chart.vue';
|
import XQueue from './queue.chart.vue';
|
||||||
import XHeader from './_header_.vue';
|
import XHeader from './_header_.vue';
|
||||||
import type { Ref } from 'vue';
|
import type { Ref } from 'vue';
|
||||||
|
@ -38,7 +40,7 @@ function clear() {
|
||||||
}).then(({ canceled }) => {
|
}).then(({ canceled }) => {
|
||||||
if (canceled) return;
|
if (canceled) return;
|
||||||
|
|
||||||
os.apiWithDialog('admin/queue/clear');
|
os.apiWithDialog('admin/queue/clear', { type: tab.value, state: '*' });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -257,6 +257,9 @@ type AdminMetaResponse = operations['admin___meta']['responses']['200']['content
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type AdminPromoCreateRequest = operations['admin___promo___create']['requestBody']['content']['application/json'];
|
type AdminPromoCreateRequest = operations['admin___promo___create']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
|
// @public (undocumented)
|
||||||
|
type AdminQueueClearRequest = operations['admin___queue___clear']['requestBody']['content']['application/json'];
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type AdminQueueDeliverDelayedResponse = operations['admin___queue___deliver-delayed']['responses']['200']['content']['application/json'];
|
type AdminQueueDeliverDelayedResponse = operations['admin___queue___deliver-delayed']['responses']['200']['content']['application/json'];
|
||||||
|
|
||||||
|
@ -1525,6 +1528,7 @@ declare namespace entities {
|
||||||
AdminInviteListResponse,
|
AdminInviteListResponse,
|
||||||
AdminMetaResponse,
|
AdminMetaResponse,
|
||||||
AdminPromoCreateRequest,
|
AdminPromoCreateRequest,
|
||||||
|
AdminQueueClearRequest,
|
||||||
AdminQueueDeliverDelayedResponse,
|
AdminQueueDeliverDelayedResponse,
|
||||||
AdminQueueInboxDelayedResponse,
|
AdminQueueInboxDelayedResponse,
|
||||||
AdminQueuePromoteRequest,
|
AdminQueuePromoteRequest,
|
||||||
|
|
|
@ -75,6 +75,7 @@ import type {
|
||||||
AdminInviteListResponse,
|
AdminInviteListResponse,
|
||||||
AdminMetaResponse,
|
AdminMetaResponse,
|
||||||
AdminPromoCreateRequest,
|
AdminPromoCreateRequest,
|
||||||
|
AdminQueueClearRequest,
|
||||||
AdminQueueDeliverDelayedResponse,
|
AdminQueueDeliverDelayedResponse,
|
||||||
AdminQueueInboxDelayedResponse,
|
AdminQueueInboxDelayedResponse,
|
||||||
AdminQueuePromoteRequest,
|
AdminQueuePromoteRequest,
|
||||||
|
@ -690,7 +691,7 @@ export type Endpoints = {
|
||||||
'admin/invite/list': { req: AdminInviteListRequest; res: AdminInviteListResponse };
|
'admin/invite/list': { req: AdminInviteListRequest; res: AdminInviteListResponse };
|
||||||
'admin/meta': { req: EmptyRequest; res: AdminMetaResponse };
|
'admin/meta': { req: EmptyRequest; res: AdminMetaResponse };
|
||||||
'admin/promo/create': { req: AdminPromoCreateRequest; res: EmptyResponse };
|
'admin/promo/create': { req: AdminPromoCreateRequest; res: EmptyResponse };
|
||||||
'admin/queue/clear': { req: EmptyRequest; res: EmptyResponse };
|
'admin/queue/clear': { req: AdminQueueClearRequest; res: EmptyResponse };
|
||||||
'admin/queue/deliver-delayed': { req: EmptyRequest; res: AdminQueueDeliverDelayedResponse };
|
'admin/queue/deliver-delayed': { req: EmptyRequest; res: AdminQueueDeliverDelayedResponse };
|
||||||
'admin/queue/inbox-delayed': { req: EmptyRequest; res: AdminQueueInboxDelayedResponse };
|
'admin/queue/inbox-delayed': { req: EmptyRequest; res: AdminQueueInboxDelayedResponse };
|
||||||
'admin/queue/promote': { req: AdminQueuePromoteRequest; res: EmptyResponse };
|
'admin/queue/promote': { req: AdminQueuePromoteRequest; res: EmptyResponse };
|
||||||
|
|
|
@ -78,6 +78,7 @@ export type AdminInviteListRequest = operations['admin___invite___list']['reques
|
||||||
export type AdminInviteListResponse = operations['admin___invite___list']['responses']['200']['content']['application/json'];
|
export type AdminInviteListResponse = operations['admin___invite___list']['responses']['200']['content']['application/json'];
|
||||||
export type AdminMetaResponse = operations['admin___meta']['responses']['200']['content']['application/json'];
|
export type AdminMetaResponse = operations['admin___meta']['responses']['200']['content']['application/json'];
|
||||||
export type AdminPromoCreateRequest = operations['admin___promo___create']['requestBody']['content']['application/json'];
|
export type AdminPromoCreateRequest = operations['admin___promo___create']['requestBody']['content']['application/json'];
|
||||||
|
export type AdminQueueClearRequest = operations['admin___queue___clear']['requestBody']['content']['application/json'];
|
||||||
export type AdminQueueDeliverDelayedResponse = operations['admin___queue___deliver-delayed']['responses']['200']['content']['application/json'];
|
export type AdminQueueDeliverDelayedResponse = operations['admin___queue___deliver-delayed']['responses']['200']['content']['application/json'];
|
||||||
export type AdminQueueInboxDelayedResponse = operations['admin___queue___inbox-delayed']['responses']['200']['content']['application/json'];
|
export type AdminQueueInboxDelayedResponse = operations['admin___queue___inbox-delayed']['responses']['200']['content']['application/json'];
|
||||||
export type AdminQueuePromoteRequest = operations['admin___queue___promote']['requestBody']['content']['application/json'];
|
export type AdminQueuePromoteRequest = operations['admin___queue___promote']['requestBody']['content']['application/json'];
|
||||||
|
|
|
@ -8805,6 +8805,16 @@ export type operations = {
|
||||||
* **Credential required**: *Yes* / **Permission**: *write:admin:queue*
|
* **Credential required**: *Yes* / **Permission**: *write:admin:queue*
|
||||||
*/
|
*/
|
||||||
admin___queue___clear: {
|
admin___queue___clear: {
|
||||||
|
requestBody: {
|
||||||
|
content: {
|
||||||
|
'application/json': {
|
||||||
|
/** @enum {string} */
|
||||||
|
type: 'system' | 'endedPollNotification' | 'deliver' | 'inbox' | 'db' | 'relationship' | 'objectStorage' | 'userWebhookDeliver' | 'systemWebhookDeliver';
|
||||||
|
/** @enum {string} */
|
||||||
|
state: '*' | 'wait' | 'delayed';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
responses: {
|
responses: {
|
||||||
/** @description OK (without any results) */
|
/** @description OK (without any results) */
|
||||||
204: {
|
204: {
|
||||||
|
|
Loading…
Reference in New Issue