Merge pull request #86 from MisskeyIO/revert-bullmq
Revert "enhance(backend): migrate bull to bullmq (#10910)"
This commit is contained in:
commit
e8cf53a1ea
|
@ -78,7 +78,7 @@
|
||||||
"autwh": "0.1.0",
|
"autwh": "0.1.0",
|
||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"blurhash": "2.0.5",
|
"blurhash": "2.0.5",
|
||||||
"bullmq": "3.15.0",
|
"bull": "4.10.4",
|
||||||
"cacheable-lookup": "6.1.0",
|
"cacheable-lookup": "6.1.0",
|
||||||
"cbor": "9.0.0",
|
"cbor": "9.0.0",
|
||||||
"chalk": "5.2.0",
|
"chalk": "5.2.0",
|
||||||
|
|
|
@ -34,7 +34,6 @@ export async function jobQueue() {
|
||||||
});
|
});
|
||||||
jobQueue.enableShutdownHooks();
|
jobQueue.enableShutdownHooks();
|
||||||
|
|
||||||
jobQueue.get(QueueProcessorService).start();
|
|
||||||
jobQueue.get(ChartManagementService).start();
|
jobQueue.get(ChartManagementService).start();
|
||||||
|
|
||||||
return jobQueue;
|
return jobQueue;
|
||||||
|
|
|
@ -510,7 +510,7 @@ export class NoteCreateService implements OnApplicationShutdown {
|
||||||
|
|
||||||
if (data.poll && data.poll.expiresAt) {
|
if (data.poll && data.poll.expiresAt) {
|
||||||
const delay = data.poll.expiresAt.getTime() - Date.now();
|
const delay = data.poll.expiresAt.getTime() - Date.now();
|
||||||
this.queueService.endedPollNotificationQueue.add(note.id, {
|
this.queueService.endedPollNotificationQueue.add({
|
||||||
noteId: note.id,
|
noteId: note.id,
|
||||||
}, {
|
}, {
|
||||||
delay,
|
delay,
|
||||||
|
|
|
@ -1,11 +1,42 @@
|
||||||
import { setTimeout } from 'node:timers/promises';
|
import { setTimeout } from 'node:timers/promises';
|
||||||
import { Inject, Module, OnApplicationShutdown } from '@nestjs/common';
|
import { Inject, Module, OnApplicationShutdown } from '@nestjs/common';
|
||||||
import * as Bull from 'bullmq';
|
import Bull from 'bull';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import type { Config } from '@/config.js';
|
import type { Config } from '@/config.js';
|
||||||
import { QUEUE, baseQueueOptions } from '@/queue/const.js';
|
|
||||||
import type { Provider } from '@nestjs/common';
|
import type { Provider } from '@nestjs/common';
|
||||||
import type { DeliverJobData, InboxJobData, EndedPollNotificationJobData, WebhookDeliverJobData, RelationshipJobData } from '../queue/types.js';
|
import type { DeliverJobData, InboxJobData, DbJobData, ObjectStorageJobData, EndedPollNotificationJobData, WebhookDeliverJobData, RelationshipJobData, DbJobMap } from '../queue/types.js';
|
||||||
|
|
||||||
|
function q<T>(config: Config, name: string, limitPerSec = -1) {
|
||||||
|
return new Bull<T>(name, {
|
||||||
|
redis: {
|
||||||
|
port: config.redisForJobQueue.port,
|
||||||
|
host: config.redisForJobQueue.host,
|
||||||
|
family: config.redisForJobQueue.family == null ? 0 : config.redisForJobQueue.family,
|
||||||
|
password: config.redisForJobQueue.pass,
|
||||||
|
db: config.redisForJobQueue.db ?? 0,
|
||||||
|
},
|
||||||
|
prefix: config.redisForJobQueue.prefix ? `${config.redisForJobQueue.prefix}:queue` : 'queue',
|
||||||
|
limiter: limitPerSec > 0 ? {
|
||||||
|
max: limitPerSec,
|
||||||
|
duration: 1000,
|
||||||
|
} : undefined,
|
||||||
|
settings: {
|
||||||
|
backoffStrategies: {
|
||||||
|
apBackoff,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// ref. https://github.com/misskey-dev/misskey/pull/7635#issue-971097019
|
||||||
|
function apBackoff(attemptsMade: number, err: Error) {
|
||||||
|
const baseDelay = 60 * 1000; // 1min
|
||||||
|
const maxBackoff = 8 * 60 * 60 * 1000; // 8hours
|
||||||
|
let backoff = (Math.pow(2, attemptsMade) - 1) * baseDelay;
|
||||||
|
backoff = Math.min(backoff, maxBackoff);
|
||||||
|
backoff += Math.round(backoff * Math.random() * 0.2);
|
||||||
|
return backoff;
|
||||||
|
}
|
||||||
|
|
||||||
export type SystemQueue = Bull.Queue<Record<string, unknown>>;
|
export type SystemQueue = Bull.Queue<Record<string, unknown>>;
|
||||||
export type EndedPollNotificationQueue = Bull.Queue<EndedPollNotificationJobData>;
|
export type EndedPollNotificationQueue = Bull.Queue<EndedPollNotificationJobData>;
|
||||||
|
@ -18,49 +49,49 @@ export type WebhookDeliverQueue = Bull.Queue<WebhookDeliverJobData>;
|
||||||
|
|
||||||
const $system: Provider = {
|
const $system: Provider = {
|
||||||
provide: 'queue:system',
|
provide: 'queue:system',
|
||||||
useFactory: (config: Config) => new Bull.Queue(QUEUE.SYSTEM, baseQueueOptions(config, QUEUE.SYSTEM)),
|
useFactory: (config: Config) => q(config, 'system'),
|
||||||
inject: [DI.config],
|
inject: [DI.config],
|
||||||
};
|
};
|
||||||
|
|
||||||
const $endedPollNotification: Provider = {
|
const $endedPollNotification: Provider = {
|
||||||
provide: 'queue:endedPollNotification',
|
provide: 'queue:endedPollNotification',
|
||||||
useFactory: (config: Config) => new Bull.Queue(QUEUE.ENDED_POLL_NOTIFICATION, baseQueueOptions(config, QUEUE.ENDED_POLL_NOTIFICATION)),
|
useFactory: (config: Config) => q(config, 'endedPollNotification'),
|
||||||
inject: [DI.config],
|
inject: [DI.config],
|
||||||
};
|
};
|
||||||
|
|
||||||
const $deliver: Provider = {
|
const $deliver: Provider = {
|
||||||
provide: 'queue:deliver',
|
provide: 'queue:deliver',
|
||||||
useFactory: (config: Config) => new Bull.Queue(QUEUE.DELIVER, baseQueueOptions(config, QUEUE.DELIVER)),
|
useFactory: (config: Config) => q(config, 'deliver', config.deliverJobPerSec ?? 128),
|
||||||
inject: [DI.config],
|
inject: [DI.config],
|
||||||
};
|
};
|
||||||
|
|
||||||
const $inbox: Provider = {
|
const $inbox: Provider = {
|
||||||
provide: 'queue:inbox',
|
provide: 'queue:inbox',
|
||||||
useFactory: (config: Config) => new Bull.Queue(QUEUE.INBOX, baseQueueOptions(config, QUEUE.INBOX)),
|
useFactory: (config: Config) => q(config, 'inbox', config.inboxJobPerSec ?? 16),
|
||||||
inject: [DI.config],
|
inject: [DI.config],
|
||||||
};
|
};
|
||||||
|
|
||||||
const $db: Provider = {
|
const $db: Provider = {
|
||||||
provide: 'queue:db',
|
provide: 'queue:db',
|
||||||
useFactory: (config: Config) => new Bull.Queue(QUEUE.DB, baseQueueOptions(config, QUEUE.DB)),
|
useFactory: (config: Config) => q(config, 'db'),
|
||||||
inject: [DI.config],
|
inject: [DI.config],
|
||||||
};
|
};
|
||||||
|
|
||||||
const $relationship: Provider = {
|
const $relationship: Provider = {
|
||||||
provide: 'queue:relationship',
|
provide: 'queue:relationship',
|
||||||
useFactory: (config: Config) => new Bull.Queue(QUEUE.RELATIONSHIP, baseQueueOptions(config, QUEUE.RELATIONSHIP)),
|
useFactory: (config: Config) => q(config, 'relationship', config.relashionshipJobPerSec ?? 64),
|
||||||
inject: [DI.config],
|
inject: [DI.config],
|
||||||
};
|
};
|
||||||
|
|
||||||
const $objectStorage: Provider = {
|
const $objectStorage: Provider = {
|
||||||
provide: 'queue:objectStorage',
|
provide: 'queue:objectStorage',
|
||||||
useFactory: (config: Config) => new Bull.Queue(QUEUE.OBJECT_STORAGE, baseQueueOptions(config, QUEUE.OBJECT_STORAGE)),
|
useFactory: (config: Config) => q(config, 'objectStorage'),
|
||||||
inject: [DI.config],
|
inject: [DI.config],
|
||||||
};
|
};
|
||||||
|
|
||||||
const $webhookDeliver: Provider = {
|
const $webhookDeliver: Provider = {
|
||||||
provide: 'queue:webhookDeliver',
|
provide: 'queue:webhookDeliver',
|
||||||
useFactory: (config: Config) => new Bull.Queue(QUEUE.WEBHOOK_DELIVER, baseQueueOptions(config, QUEUE.WEBHOOK_DELIVER)),
|
useFactory: (config: Config) => q(config, 'webhookDeliver', 64),
|
||||||
inject: [DI.config],
|
inject: [DI.config],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
|
import Bull from 'bull';
|
||||||
import type { IActivity } from '@/core/activitypub/type.js';
|
import type { IActivity } from '@/core/activitypub/type.js';
|
||||||
import type { DriveFile } from '@/models/entities/DriveFile.js';
|
import type { DriveFile } from '@/models/entities/DriveFile.js';
|
||||||
import type { Webhook, webhookEventTypes } from '@/models/entities/Webhook.js';
|
import type { Webhook, webhookEventTypes } from '@/models/entities/Webhook.js';
|
||||||
|
@ -10,7 +11,6 @@ import type { Antenna } from '@/server/api/endpoints/i/import-antennas.js';
|
||||||
import type { DbQueue, DeliverQueue, EndedPollNotificationQueue, InboxQueue, ObjectStorageQueue, RelationshipQueue, SystemQueue, WebhookDeliverQueue } from './QueueModule.js';
|
import type { DbQueue, DeliverQueue, EndedPollNotificationQueue, InboxQueue, ObjectStorageQueue, RelationshipQueue, SystemQueue, WebhookDeliverQueue } from './QueueModule.js';
|
||||||
import type { DbJobData, RelationshipJobData, ThinUser } from '../queue/types.js';
|
import type { DbJobData, RelationshipJobData, ThinUser } from '../queue/types.js';
|
||||||
import type httpSignature from '@peertube/http-signature';
|
import type httpSignature from '@peertube/http-signature';
|
||||||
import type * as Bull from 'bullmq';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class QueueService {
|
export class QueueService {
|
||||||
|
@ -26,43 +26,7 @@ export class QueueService {
|
||||||
@Inject('queue:relationship') public relationshipQueue: RelationshipQueue,
|
@Inject('queue:relationship') public relationshipQueue: RelationshipQueue,
|
||||||
@Inject('queue:objectStorage') public objectStorageQueue: ObjectStorageQueue,
|
@Inject('queue:objectStorage') public objectStorageQueue: ObjectStorageQueue,
|
||||||
@Inject('queue:webhookDeliver') public webhookDeliverQueue: WebhookDeliverQueue,
|
@Inject('queue:webhookDeliver') public webhookDeliverQueue: WebhookDeliverQueue,
|
||||||
) {
|
) {}
|
||||||
this.systemQueue.add('tickCharts', {
|
|
||||||
}, {
|
|
||||||
repeat: { pattern: '55 * * * *' },
|
|
||||||
removeOnComplete: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.systemQueue.add('resyncCharts', {
|
|
||||||
}, {
|
|
||||||
repeat: { pattern: '0 0 * * *' },
|
|
||||||
removeOnComplete: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.systemQueue.add('cleanCharts', {
|
|
||||||
}, {
|
|
||||||
repeat: { pattern: '0 0 * * *' },
|
|
||||||
removeOnComplete: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.systemQueue.add('aggregateRetention', {
|
|
||||||
}, {
|
|
||||||
repeat: { pattern: '0 0 * * *' },
|
|
||||||
removeOnComplete: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.systemQueue.add('clean', {
|
|
||||||
}, {
|
|
||||||
repeat: { pattern: '0 0 * * *' },
|
|
||||||
removeOnComplete: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.systemQueue.add('checkExpiredMutings', {
|
|
||||||
}, {
|
|
||||||
repeat: { pattern: '*/5 * * * *' },
|
|
||||||
removeOnComplete: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public deliver(user: ThinUser, content: IActivity | null, to: string | null, isSharedInbox: boolean) {
|
public deliver(user: ThinUser, content: IActivity | null, to: string | null, isSharedInbox: boolean) {
|
||||||
|
@ -78,10 +42,11 @@ export class QueueService {
|
||||||
isSharedInbox,
|
isSharedInbox,
|
||||||
};
|
};
|
||||||
|
|
||||||
return this.deliverQueue.add(to, data, {
|
return this.deliverQueue.add(data, {
|
||||||
attempts: this.config.deliverJobMaxAttempts ?? 12,
|
attempts: this.config.deliverJobMaxAttempts ?? 12,
|
||||||
|
timeout: 1 * 60 * 1000, // 1min
|
||||||
backoff: {
|
backoff: {
|
||||||
type: 'custom',
|
type: 'apBackoff',
|
||||||
},
|
},
|
||||||
removeOnComplete: true,
|
removeOnComplete: true,
|
||||||
removeOnFail: true,
|
removeOnFail: true,
|
||||||
|
@ -95,10 +60,11 @@ export class QueueService {
|
||||||
signature,
|
signature,
|
||||||
};
|
};
|
||||||
|
|
||||||
return this.inboxQueue.add('', data, {
|
return this.inboxQueue.add(data, {
|
||||||
attempts: this.config.inboxJobMaxAttempts ?? 8,
|
attempts: this.config.inboxJobMaxAttempts ?? 8,
|
||||||
|
timeout: 5 * 60 * 1000, // 5min
|
||||||
backoff: {
|
backoff: {
|
||||||
type: 'custom',
|
type: 'apBackoff',
|
||||||
},
|
},
|
||||||
removeOnComplete: true,
|
removeOnComplete: true,
|
||||||
removeOnFail: true,
|
removeOnFail: true,
|
||||||
|
@ -246,7 +212,7 @@ export class QueueService {
|
||||||
private generateToDbJobData<T extends 'importFollowingToDb' | 'importBlockingToDb', D extends DbJobData<T>>(name: T, data: D): {
|
private generateToDbJobData<T extends 'importFollowingToDb' | 'importBlockingToDb', D extends DbJobData<T>>(name: T, data: D): {
|
||||||
name: string,
|
name: string,
|
||||||
data: D,
|
data: D,
|
||||||
opts: Bull.JobsOptions,
|
opts: Bull.JobOptions,
|
||||||
} {
|
} {
|
||||||
return {
|
return {
|
||||||
name,
|
name,
|
||||||
|
@ -333,10 +299,10 @@ export class QueueService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
private generateRelationshipJobData(name: 'follow' | 'unfollow' | 'block' | 'unblock', data: RelationshipJobData, opts: Bull.JobsOptions = {}): {
|
private generateRelationshipJobData(name: 'follow' | 'unfollow' | 'block' | 'unblock', data: RelationshipJobData, opts: Bull.JobOptions = {}): {
|
||||||
name: string,
|
name: string,
|
||||||
data: RelationshipJobData,
|
data: RelationshipJobData,
|
||||||
opts: Bull.JobsOptions,
|
opts: Bull.JobOptions,
|
||||||
} {
|
} {
|
||||||
return {
|
return {
|
||||||
name,
|
name,
|
||||||
|
@ -385,10 +351,11 @@ export class QueueService {
|
||||||
eventId: uuid(),
|
eventId: uuid(),
|
||||||
};
|
};
|
||||||
|
|
||||||
return this.webhookDeliverQueue.add(webhook.id, data, {
|
return this.webhookDeliverQueue.add(data, {
|
||||||
attempts: 4,
|
attempts: 4,
|
||||||
|
timeout: 1 * 60 * 1000, // 1min
|
||||||
backoff: {
|
backoff: {
|
||||||
type: 'custom',
|
type: 'apBackoff',
|
||||||
},
|
},
|
||||||
removeOnComplete: true,
|
removeOnComplete: true,
|
||||||
removeOnFail: true,
|
removeOnFail: true,
|
||||||
|
@ -400,11 +367,11 @@ export class QueueService {
|
||||||
this.deliverQueue.once('cleaned', (jobs, status) => {
|
this.deliverQueue.once('cleaned', (jobs, status) => {
|
||||||
//deliverLogger.succ(`Cleaned ${jobs.length} ${status} jobs`);
|
//deliverLogger.succ(`Cleaned ${jobs.length} ${status} jobs`);
|
||||||
});
|
});
|
||||||
this.deliverQueue.clean(0, Infinity, 'delayed');
|
this.deliverQueue.clean(0, 'delayed');
|
||||||
|
|
||||||
this.inboxQueue.once('cleaned', (jobs, status) => {
|
this.inboxQueue.once('cleaned', (jobs, status) => {
|
||||||
//inboxLogger.succ(`Cleaned ${jobs.length} ${status} jobs`);
|
//inboxLogger.succ(`Cleaned ${jobs.length} ${status} jobs`);
|
||||||
});
|
});
|
||||||
this.inboxQueue.clean(0, Infinity, 'delayed');
|
this.inboxQueue.clean(0, 'delayed');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ import { PollService } from '@/core/PollService.js';
|
||||||
import { StatusError } from '@/misc/status-error.js';
|
import { StatusError } from '@/misc/status-error.js';
|
||||||
import { UtilityService } from '@/core/UtilityService.js';
|
import { UtilityService } from '@/core/UtilityService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { checkHttps } from '@/misc/check-https.js';
|
|
||||||
import { getOneApId, getApId, getOneApHrefNullable, validPost, isEmoji, getApType } from '../type.js';
|
import { getOneApId, getApId, getOneApHrefNullable, validPost, isEmoji, getApType } from '../type.js';
|
||||||
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
||||||
import { ApLoggerService } from '../ApLoggerService.js';
|
import { ApLoggerService } from '../ApLoggerService.js';
|
||||||
|
@ -33,6 +32,7 @@ import { ApQuestionService } from './ApQuestionService.js';
|
||||||
import { ApImageService } from './ApImageService.js';
|
import { ApImageService } from './ApImageService.js';
|
||||||
import type { Resolver } from '../ApResolverService.js';
|
import type { Resolver } from '../ApResolverService.js';
|
||||||
import type { IObject, IPost } from '../type.js';
|
import type { IObject, IPost } from '../type.js';
|
||||||
|
import { checkHttps } from '@/misc/check-https.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ApNoteService {
|
export class ApNoteService {
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import Xev from 'xev';
|
import Xev from 'xev';
|
||||||
import * as Bull from 'bullmq';
|
|
||||||
import { QueueService } from '@/core/QueueService.js';
|
import { QueueService } from '@/core/QueueService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
|
||||||
import type { Config } from '@/config.js';
|
|
||||||
import { QUEUE, baseQueueOptions } from '@/queue/const.js';
|
|
||||||
import type { OnApplicationShutdown } from '@nestjs/common';
|
import type { OnApplicationShutdown } from '@nestjs/common';
|
||||||
|
|
||||||
const ev = new Xev();
|
const ev = new Xev();
|
||||||
|
@ -17,9 +13,6 @@ export class QueueStatsService implements OnApplicationShutdown {
|
||||||
private intervalId: NodeJS.Timer;
|
private intervalId: NodeJS.Timer;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(DI.config)
|
|
||||||
private config: Config,
|
|
||||||
|
|
||||||
private queueService: QueueService,
|
private queueService: QueueService,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
@ -38,14 +31,11 @@ export class QueueStatsService implements OnApplicationShutdown {
|
||||||
let activeDeliverJobs = 0;
|
let activeDeliverJobs = 0;
|
||||||
let activeInboxJobs = 0;
|
let activeInboxJobs = 0;
|
||||||
|
|
||||||
const deliverQueueEvents = new Bull.QueueEvents(QUEUE.DELIVER, baseQueueOptions(this.config, QUEUE.DELIVER));
|
this.queueService.deliverQueue.on('global:active', () => {
|
||||||
const inboxQueueEvents = new Bull.QueueEvents(QUEUE.INBOX, baseQueueOptions(this.config, QUEUE.INBOX));
|
|
||||||
|
|
||||||
deliverQueueEvents.on('active', () => {
|
|
||||||
activeDeliverJobs++;
|
activeDeliverJobs++;
|
||||||
});
|
});
|
||||||
|
|
||||||
inboxQueueEvents.on('active', () => {
|
this.queueService.inboxQueue.on('global:active', () => {
|
||||||
activeInboxJobs++;
|
activeInboxJobs++;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,7 @@ const dateTimeIntervals = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export function dateUTC(time: number[]): Date {
|
export function dateUTC(time: number[]): Date {
|
||||||
const d =
|
const d = time.length === 2 ? Date.UTC(time[0], time[1])
|
||||||
time.length === 2 ? Date.UTC(time[0], time[1])
|
|
||||||
: time.length === 3 ? Date.UTC(time[0], time[1], time[2])
|
: time.length === 3 ? Date.UTC(time[0], time[1], time[2])
|
||||||
: time.length === 4 ? Date.UTC(time[0], time[1], time[2], time[3])
|
: time.length === 4 ? Date.UTC(time[0], time[1], time[2], time[3])
|
||||||
: time.length === 5 ? Date.UTC(time[0], time[1], time[2], time[3], time[4])
|
: time.length === 5 ? Date.UTC(time[0], time[1], time[2], time[3], time[4])
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
|
import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common';
|
||||||
import * as Bull from 'bullmq';
|
|
||||||
import type { Config } from '@/config.js';
|
import type { Config } from '@/config.js';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import type Logger from '@/logger.js';
|
import type Logger from '@/logger.js';
|
||||||
|
import { QueueService } from '@/core/QueueService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
|
import { getJobInfo } from './get-job-info.js';
|
||||||
import { WebhookDeliverProcessorService } from './processors/WebhookDeliverProcessorService.js';
|
import { WebhookDeliverProcessorService } from './processors/WebhookDeliverProcessorService.js';
|
||||||
import { EndedPollNotificationProcessorService } from './processors/EndedPollNotificationProcessorService.js';
|
import { EndedPollNotificationProcessorService } from './processors/EndedPollNotificationProcessorService.js';
|
||||||
import { DeliverProcessorService } from './processors/DeliverProcessorService.js';
|
import { DeliverProcessorService } from './processors/DeliverProcessorService.js';
|
||||||
|
@ -34,51 +35,17 @@ import { CheckExpiredMutingsProcessorService } from './processors/CheckExpiredMu
|
||||||
import { CleanProcessorService } from './processors/CleanProcessorService.js';
|
import { CleanProcessorService } from './processors/CleanProcessorService.js';
|
||||||
import { AggregateRetentionProcessorService } from './processors/AggregateRetentionProcessorService.js';
|
import { AggregateRetentionProcessorService } from './processors/AggregateRetentionProcessorService.js';
|
||||||
import { QueueLoggerService } from './QueueLoggerService.js';
|
import { QueueLoggerService } from './QueueLoggerService.js';
|
||||||
import { QUEUE, baseQueueOptions } from './const.js';
|
|
||||||
|
|
||||||
// ref. https://github.com/misskey-dev/misskey/pull/7635#issue-971097019
|
|
||||||
function httpRelatedBackoff(attemptsMade: number) {
|
|
||||||
const baseDelay = 60 * 1000; // 1min
|
|
||||||
const maxBackoff = 8 * 60 * 60 * 1000; // 8hours
|
|
||||||
let backoff = (Math.pow(2, attemptsMade) - 1) * baseDelay;
|
|
||||||
backoff = Math.min(backoff, maxBackoff);
|
|
||||||
backoff += Math.round(backoff * Math.random() * 0.2);
|
|
||||||
return backoff;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getJobInfo(job: Bull.Job | undefined, increment = false): string {
|
|
||||||
if (job == null) return '-';
|
|
||||||
|
|
||||||
const age = Date.now() - job.timestamp;
|
|
||||||
|
|
||||||
const formated = age > 60000 ? `${Math.floor(age / 1000 / 60)}m`
|
|
||||||
: age > 10000 ? `${Math.floor(age / 1000)}s`
|
|
||||||
: `${age}ms`;
|
|
||||||
|
|
||||||
// onActiveとかonCompletedのattemptsMadeがなぜか0始まりなのでインクリメントする
|
|
||||||
const currentAttempts = job.attemptsMade + (increment ? 1 : 0);
|
|
||||||
const maxAttempts = job.opts ? job.opts.attempts : 0;
|
|
||||||
|
|
||||||
return `id=${job.id} attempts=${currentAttempts}/${maxAttempts} age=${formated}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class QueueProcessorService implements OnApplicationShutdown {
|
export class QueueProcessorService implements OnApplicationShutdown {
|
||||||
private logger: Logger;
|
private logger: Logger;
|
||||||
private systemQueueWorker: Bull.Worker;
|
|
||||||
private dbQueueWorker: Bull.Worker;
|
|
||||||
private deliverQueueWorker: Bull.Worker;
|
|
||||||
private inboxQueueWorker: Bull.Worker;
|
|
||||||
private webhookDeliverQueueWorker: Bull.Worker;
|
|
||||||
private relationshipQueueWorker: Bull.Worker;
|
|
||||||
private objectStorageQueueWorker: Bull.Worker;
|
|
||||||
private endedPollNotificationQueueWorker: Bull.Worker;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(DI.config)
|
@Inject(DI.config)
|
||||||
private config: Config,
|
private config: Config,
|
||||||
|
|
||||||
private queueLoggerService: QueueLoggerService,
|
private queueLoggerService: QueueLoggerService,
|
||||||
|
private queueService: QueueService,
|
||||||
private webhookDeliverProcessorService: WebhookDeliverProcessorService,
|
private webhookDeliverProcessorService: WebhookDeliverProcessorService,
|
||||||
private endedPollNotificationProcessorService: EndedPollNotificationProcessorService,
|
private endedPollNotificationProcessorService: EndedPollNotificationProcessorService,
|
||||||
private deliverProcessorService: DeliverProcessorService,
|
private deliverProcessorService: DeliverProcessorService,
|
||||||
|
@ -127,227 +94,160 @@ export class QueueProcessorService implements OnApplicationShutdown {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//#region system
|
|
||||||
this.systemQueueWorker = new Bull.Worker(QUEUE.SYSTEM, (job) => {
|
|
||||||
switch (job.name) {
|
|
||||||
case 'tickCharts': return this.tickChartsProcessorService.process();
|
|
||||||
case 'resyncCharts': return this.resyncChartsProcessorService.process();
|
|
||||||
case 'cleanCharts': return this.cleanChartsProcessorService.process();
|
|
||||||
case 'aggregateRetention': return this.aggregateRetentionProcessorService.process();
|
|
||||||
case 'checkExpiredMutings': return this.checkExpiredMutingsProcessorService.process();
|
|
||||||
case 'clean': return this.cleanProcessorService.process();
|
|
||||||
default: throw new Error(`unrecognized job type ${job.name} for system`);
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
...baseQueueOptions(this.config, QUEUE.SYSTEM),
|
|
||||||
autorun: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const systemLogger = this.logger.createSubLogger('system');
|
const systemLogger = this.logger.createSubLogger('system');
|
||||||
|
|
||||||
this.systemQueueWorker
|
|
||||||
.on('active', (job) => systemLogger.debug(`active id=${job.id}`))
|
|
||||||
.on('completed', (job, result) => systemLogger.debug(`completed(${result}) id=${job.id}`))
|
|
||||||
.on('failed', (job, err) => systemLogger.warn(`failed(${err}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }))
|
|
||||||
.on('error', (err: Error) => systemLogger.error(`error ${err}`, { e: renderError(err) }))
|
|
||||||
.on('stalled', (jobId) => systemLogger.warn(`stalled id=${jobId}`));
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
//#region db
|
|
||||||
this.dbQueueWorker = new Bull.Worker(QUEUE.DB, (job) => {
|
|
||||||
switch (job.name) {
|
|
||||||
case 'deleteDriveFiles': return this.deleteDriveFilesProcessorService.process(job);
|
|
||||||
case 'exportCustomEmojis': return this.exportCustomEmojisProcessorService.process(job);
|
|
||||||
case 'exportNotes': return this.exportNotesProcessorService.process(job);
|
|
||||||
case 'exportFavorites': return this.exportFavoritesProcessorService.process(job);
|
|
||||||
case 'exportFollowing': return this.exportFollowingProcessorService.process(job);
|
|
||||||
case 'exportMuting': return this.exportMutingProcessorService.process(job);
|
|
||||||
case 'exportBlocking': return this.exportBlockingProcessorService.process(job);
|
|
||||||
case 'exportUserLists': return this.exportUserListsProcessorService.process(job);
|
|
||||||
case 'exportAntennas': return this.exportAntennasProcessorService.process(job);
|
|
||||||
case 'importFollowing': return this.importFollowingProcessorService.process(job);
|
|
||||||
case 'importFollowingToDb': return this.importFollowingProcessorService.processDb(job);
|
|
||||||
case 'importMuting': return this.importMutingProcessorService.process(job);
|
|
||||||
case 'importBlocking': return this.importBlockingProcessorService.process(job);
|
|
||||||
case 'importBlockingToDb': return this.importBlockingProcessorService.processDb(job);
|
|
||||||
case 'importUserLists': return this.importUserListsProcessorService.process(job);
|
|
||||||
case 'importCustomEmojis': return this.importCustomEmojisProcessorService.process(job);
|
|
||||||
case 'importAntennas': return this.importAntennasProcessorService.process(job);
|
|
||||||
case 'deleteAccount': return this.deleteAccountProcessorService.process(job);
|
|
||||||
default: throw new Error(`unrecognized job type ${job.name} for db`);
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
...baseQueueOptions(this.config, QUEUE.DB),
|
|
||||||
autorun: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const dbLogger = this.logger.createSubLogger('db');
|
|
||||||
|
|
||||||
this.dbQueueWorker
|
|
||||||
.on('active', (job) => dbLogger.debug(`active id=${job.id}`))
|
|
||||||
.on('completed', (job, result) => dbLogger.debug(`completed(${result}) id=${job.id}`))
|
|
||||||
.on('failed', (job, err) => dbLogger.warn(`failed(${err}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }))
|
|
||||||
.on('error', (err: Error) => dbLogger.error(`error ${err}`, { e: renderError(err) }))
|
|
||||||
.on('stalled', (jobId) => dbLogger.warn(`stalled id=${jobId}`));
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
//#region deliver
|
|
||||||
this.deliverQueueWorker = new Bull.Worker(QUEUE.DELIVER, (job) => this.deliverProcessorService.process(job), {
|
|
||||||
...baseQueueOptions(this.config, QUEUE.DELIVER),
|
|
||||||
autorun: false,
|
|
||||||
concurrency: this.config.deliverJobConcurrency ?? 128,
|
|
||||||
limiter: {
|
|
||||||
max: this.config.deliverJobPerSec ?? 128,
|
|
||||||
duration: 1000,
|
|
||||||
},
|
|
||||||
settings: {
|
|
||||||
backoffStrategy: httpRelatedBackoff,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const deliverLogger = this.logger.createSubLogger('deliver');
|
const deliverLogger = this.logger.createSubLogger('deliver');
|
||||||
|
|
||||||
this.deliverQueueWorker
|
|
||||||
.on('active', (job) => deliverLogger.debug(`active ${getJobInfo(job, true)} to=${job.data.to}`))
|
|
||||||
.on('completed', (job, result) => deliverLogger.debug(`completed(${result}) ${getJobInfo(job, true)} to=${job.data.to}`))
|
|
||||||
.on('failed', (job, err) => deliverLogger.warn(`failed(${err}) ${getJobInfo(job)} to=${job ? job.data.to : '-'}`))
|
|
||||||
.on('error', (err: Error) => deliverLogger.error(`error ${err}`, { e: renderError(err) }))
|
|
||||||
.on('stalled', (jobId) => deliverLogger.warn(`stalled id=${jobId}`));
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
//#region inbox
|
|
||||||
this.inboxQueueWorker = new Bull.Worker(QUEUE.INBOX, (job) => this.inboxProcessorService.process(job), {
|
|
||||||
...baseQueueOptions(this.config, QUEUE.INBOX),
|
|
||||||
autorun: false,
|
|
||||||
concurrency: this.config.inboxJobConcurrency ?? 16,
|
|
||||||
limiter: {
|
|
||||||
max: this.config.inboxJobPerSec ?? 16,
|
|
||||||
duration: 1000,
|
|
||||||
},
|
|
||||||
settings: {
|
|
||||||
backoffStrategy: httpRelatedBackoff,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const inboxLogger = this.logger.createSubLogger('inbox');
|
|
||||||
|
|
||||||
this.inboxQueueWorker
|
|
||||||
.on('active', (job) => inboxLogger.debug(`active ${getJobInfo(job, true)}`))
|
|
||||||
.on('completed', (job, result) => inboxLogger.debug(`completed(${result}) ${getJobInfo(job, true)}`))
|
|
||||||
.on('failed', (job, err) => inboxLogger.warn(`failed(${err}) ${getJobInfo(job)} activity=${job ? (job.data.activity ? job.data.activity.id : 'none') : '-'}`, { job, e: renderError(err) }))
|
|
||||||
.on('error', (err: Error) => inboxLogger.error(`error ${err}`, { e: renderError(err) }))
|
|
||||||
.on('stalled', (jobId) => inboxLogger.warn(`stalled id=${jobId}`));
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
//#region webhook deliver
|
|
||||||
this.webhookDeliverQueueWorker = new Bull.Worker(QUEUE.WEBHOOK_DELIVER, (job) => this.webhookDeliverProcessorService.process(job), {
|
|
||||||
...baseQueueOptions(this.config, QUEUE.WEBHOOK_DELIVER),
|
|
||||||
autorun: false,
|
|
||||||
concurrency: 64,
|
|
||||||
limiter: {
|
|
||||||
max: 64,
|
|
||||||
duration: 1000,
|
|
||||||
},
|
|
||||||
settings: {
|
|
||||||
backoffStrategy: httpRelatedBackoff,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const webhookLogger = this.logger.createSubLogger('webhook');
|
const webhookLogger = this.logger.createSubLogger('webhook');
|
||||||
|
const inboxLogger = this.logger.createSubLogger('inbox');
|
||||||
this.webhookDeliverQueueWorker
|
const dbLogger = this.logger.createSubLogger('db');
|
||||||
.on('active', (job) => webhookLogger.debug(`active ${getJobInfo(job, true)} to=${job.data.to}`))
|
|
||||||
.on('completed', (job, result) => webhookLogger.debug(`completed(${result}) ${getJobInfo(job, true)} to=${job.data.to}`))
|
|
||||||
.on('failed', (job, err) => webhookLogger.warn(`failed(${err}) ${getJobInfo(job)} to=${job ? job.data.to : '-'}`))
|
|
||||||
.on('error', (err: Error) => webhookLogger.error(`error ${err}`, { e: renderError(err) }))
|
|
||||||
.on('stalled', (jobId) => webhookLogger.warn(`stalled id=${jobId}`));
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
//#region relationship
|
|
||||||
this.relationshipQueueWorker = new Bull.Worker(QUEUE.RELATIONSHIP, (job) => {
|
|
||||||
switch (job.name) {
|
|
||||||
case 'follow': return this.relationshipProcessorService.processFollow(job);
|
|
||||||
case 'unfollow': return this.relationshipProcessorService.processUnfollow(job);
|
|
||||||
case 'block': return this.relationshipProcessorService.processBlock(job);
|
|
||||||
case 'unblock': return this.relationshipProcessorService.processUnblock(job);
|
|
||||||
default: throw new Error(`unrecognized job type ${job.name} for relationship`);
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
...baseQueueOptions(this.config, QUEUE.RELATIONSHIP),
|
|
||||||
autorun: false,
|
|
||||||
concurrency: this.config.relashionshipJobConcurrency ?? 16,
|
|
||||||
limiter: {
|
|
||||||
max: this.config.relashionshipJobPerSec ?? 64,
|
|
||||||
duration: 1000,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const relationshipLogger = this.logger.createSubLogger('relationship');
|
const relationshipLogger = this.logger.createSubLogger('relationship');
|
||||||
|
|
||||||
this.relationshipQueueWorker
|
|
||||||
.on('active', (job) => relationshipLogger.debug(`active id=${job.id}`))
|
|
||||||
.on('completed', (job, result) => relationshipLogger.debug(`completed(${result}) id=${job.id}`))
|
|
||||||
.on('failed', (job, err) => relationshipLogger.warn(`failed(${err}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }))
|
|
||||||
.on('error', (err: Error) => relationshipLogger.error(`error ${err}`, { e: renderError(err) }))
|
|
||||||
.on('stalled', (jobId) => relationshipLogger.warn(`stalled id=${jobId}`));
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
//#region object storage
|
|
||||||
this.objectStorageQueueWorker = new Bull.Worker(QUEUE.OBJECT_STORAGE, (job) => {
|
|
||||||
switch (job.name) {
|
|
||||||
case 'deleteFile': return this.deleteFileProcessorService.process(job);
|
|
||||||
case 'cleanRemoteFiles': return this.cleanRemoteFilesProcessorService.process(job);
|
|
||||||
default: throw new Error(`unrecognized job type ${job.name} for objectStorage`);
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
...baseQueueOptions(this.config, QUEUE.OBJECT_STORAGE),
|
|
||||||
autorun: false,
|
|
||||||
concurrency: 16,
|
|
||||||
});
|
|
||||||
|
|
||||||
const objectStorageLogger = this.logger.createSubLogger('objectStorage');
|
const objectStorageLogger = this.logger.createSubLogger('objectStorage');
|
||||||
|
|
||||||
this.objectStorageQueueWorker
|
this.queueService.systemQueue
|
||||||
|
.on('waiting', (jobId) => systemLogger.debug(`waiting id=${jobId}`))
|
||||||
|
.on('active', (job) => systemLogger.debug(`active id=${job.id}`))
|
||||||
|
.on('completed', (job, result) => systemLogger.debug(`completed(${result}) id=${job.id}`))
|
||||||
|
.on('failed', (job, err) => systemLogger.warn(`failed(${err}) id=${job.id}`, { job, e: renderError(err) }))
|
||||||
|
.on('error', (job: any, err: Error) => systemLogger.error(`error ${err}`, { job, e: renderError(err) }))
|
||||||
|
.on('stalled', (job) => systemLogger.warn(`stalled id=${job.id}`));
|
||||||
|
|
||||||
|
this.queueService.deliverQueue
|
||||||
|
.on('waiting', (jobId) => deliverLogger.debug(`waiting id=${jobId}`))
|
||||||
|
.on('active', (job) => deliverLogger.debug(`active ${getJobInfo(job, true)} to=${job.data.to}`))
|
||||||
|
.on('completed', (job, result) => deliverLogger.debug(`completed(${result}) ${getJobInfo(job, true)} to=${job.data.to}`))
|
||||||
|
.on('failed', (job, err) => deliverLogger.warn(`failed(${err}) ${getJobInfo(job)} to=${job.data.to}`))
|
||||||
|
.on('error', (job: any, err: Error) => deliverLogger.error(`error ${err}`, { job, e: renderError(err) }))
|
||||||
|
.on('stalled', (job) => deliverLogger.warn(`stalled ${getJobInfo(job)} to=${job.data.to}`));
|
||||||
|
|
||||||
|
this.queueService.inboxQueue
|
||||||
|
.on('waiting', (jobId) => inboxLogger.debug(`waiting id=${jobId}`))
|
||||||
|
.on('active', (job) => inboxLogger.debug(`active ${getJobInfo(job, true)}`))
|
||||||
|
.on('completed', (job, result) => inboxLogger.debug(`completed(${result}) ${getJobInfo(job, true)}`))
|
||||||
|
.on('failed', (job, err) => inboxLogger.warn(`failed(${err}) ${getJobInfo(job)} activity=${job.data.activity ? job.data.activity.id : 'none'}`, { job, e: renderError(err) }))
|
||||||
|
.on('error', (job: any, err: Error) => inboxLogger.error(`error ${err}`, { job, e: renderError(err) }))
|
||||||
|
.on('stalled', (job) => inboxLogger.warn(`stalled ${getJobInfo(job)} activity=${job.data.activity ? job.data.activity.id : 'none'}`));
|
||||||
|
|
||||||
|
this.queueService.dbQueue
|
||||||
|
.on('waiting', (jobId) => dbLogger.debug(`waiting id=${jobId}`))
|
||||||
|
.on('active', (job) => dbLogger.debug(`active id=${job.id}`))
|
||||||
|
.on('completed', (job, result) => dbLogger.debug(`completed(${result}) id=${job.id}`))
|
||||||
|
.on('failed', (job, err) => dbLogger.warn(`failed(${err}) id=${job.id}`, { job, e: renderError(err) }))
|
||||||
|
.on('error', (job: any, err: Error) => dbLogger.error(`error ${err}`, { job, e: renderError(err) }))
|
||||||
|
.on('stalled', (job) => dbLogger.warn(`stalled id=${job.id}`));
|
||||||
|
|
||||||
|
this.queueService.relationshipQueue
|
||||||
|
.on('waiting', (jobId) => relationshipLogger.debug(`waiting id=${jobId}`))
|
||||||
|
.on('active', (job) => relationshipLogger.debug(`active id=${job.id}`))
|
||||||
|
.on('completed', (job, result) => relationshipLogger.debug(`completed(${result}) id=${job.id}`))
|
||||||
|
.on('failed', (job, err) => relationshipLogger.warn(`failed(${err}) id=${job.id}`, { job, e: renderError(err) }))
|
||||||
|
.on('error', (job: any, err: Error) => relationshipLogger.error(`error ${err}`, { job, e: renderError(err) }))
|
||||||
|
.on('stalled', (job) => relationshipLogger.warn(`stalled id=${job.id}`));
|
||||||
|
|
||||||
|
this.queueService.objectStorageQueue
|
||||||
|
.on('waiting', (jobId) => objectStorageLogger.debug(`waiting id=${jobId}`))
|
||||||
.on('active', (job) => objectStorageLogger.debug(`active id=${job.id}`))
|
.on('active', (job) => objectStorageLogger.debug(`active id=${job.id}`))
|
||||||
.on('completed', (job, result) => objectStorageLogger.debug(`completed(${result}) id=${job.id}`))
|
.on('completed', (job, result) => objectStorageLogger.debug(`completed(${result}) id=${job.id}`))
|
||||||
.on('failed', (job, err) => objectStorageLogger.warn(`failed(${err}) id=${job ? job.id : '-'}`, { job, e: renderError(err) }))
|
.on('failed', (job, err) => objectStorageLogger.warn(`failed(${err}) id=${job.id}`, { job, e: renderError(err) }))
|
||||||
.on('error', (err: Error) => objectStorageLogger.error(`error ${err}`, { e: renderError(err) }))
|
.on('error', (job: any, err: Error) => objectStorageLogger.error(`error ${err}`, { job, e: renderError(err) }))
|
||||||
.on('stalled', (jobId) => objectStorageLogger.warn(`stalled id=${jobId}`));
|
.on('stalled', (job) => objectStorageLogger.warn(`stalled id=${job.id}`));
|
||||||
//#endregion
|
|
||||||
|
|
||||||
//#region ended poll notification
|
this.queueService.webhookDeliverQueue
|
||||||
this.endedPollNotificationQueueWorker = new Bull.Worker(QUEUE.ENDED_POLL_NOTIFICATION, (job) => this.endedPollNotificationProcessorService.process(job), {
|
.on('waiting', (jobId) => webhookLogger.debug(`waiting id=${jobId}`))
|
||||||
...baseQueueOptions(this.config, QUEUE.ENDED_POLL_NOTIFICATION),
|
.on('active', (job) => webhookLogger.debug(`active ${getJobInfo(job, true)} to=${job.data.to}`))
|
||||||
autorun: false,
|
.on('completed', (job, result) => webhookLogger.debug(`completed(${result}) ${getJobInfo(job, true)} to=${job.data.to}`))
|
||||||
|
.on('failed', (job, err) => webhookLogger.warn(`failed(${err}) ${getJobInfo(job)} to=${job.data.to}`))
|
||||||
|
.on('error', (job: any, err: Error) => webhookLogger.error(`error ${err}`, { job, e: renderError(err) }))
|
||||||
|
.on('stalled', (job) => webhookLogger.warn(`stalled ${getJobInfo(job)} to=${job.data.to}`));
|
||||||
|
|
||||||
|
this.queueService.systemQueue.add('tickCharts', {
|
||||||
|
}, {
|
||||||
|
repeat: { cron: '55 * * * *' },
|
||||||
|
removeOnComplete: true,
|
||||||
});
|
});
|
||||||
//#endregion
|
|
||||||
|
this.queueService.systemQueue.add('resyncCharts', {
|
||||||
|
}, {
|
||||||
|
repeat: { cron: '0 0 * * *' },
|
||||||
|
removeOnComplete: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.queueService.systemQueue.add('cleanCharts', {
|
||||||
|
}, {
|
||||||
|
repeat: { cron: '0 0 * * *' },
|
||||||
|
removeOnComplete: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.queueService.systemQueue.add('aggregateRetention', {
|
||||||
|
}, {
|
||||||
|
repeat: { cron: '0 0 * * *' },
|
||||||
|
removeOnComplete: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.queueService.systemQueue.add('clean', {
|
||||||
|
}, {
|
||||||
|
repeat: { cron: '0 0 * * *' },
|
||||||
|
removeOnComplete: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.queueService.systemQueue.add('checkExpiredMutings', {
|
||||||
|
}, {
|
||||||
|
repeat: { cron: '*/5 * * * *' },
|
||||||
|
removeOnComplete: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.queueService.deliverQueue.process(this.config.deliverJobConcurrency ?? 128, (job) => this.deliverProcessorService.process(job));
|
||||||
|
this.queueService.inboxQueue.process(this.config.inboxJobConcurrency ?? 16, (job) => this.inboxProcessorService.process(job));
|
||||||
|
this.queueService.endedPollNotificationQueue.process((job, done) => this.endedPollNotificationProcessorService.process(job, done));
|
||||||
|
this.queueService.webhookDeliverQueue.process(64, (job) => this.webhookDeliverProcessorService.process(job));
|
||||||
|
|
||||||
|
this.queueService.dbQueue.process('deleteDriveFiles', (job, done) => this.deleteDriveFilesProcessorService.process(job, done));
|
||||||
|
this.queueService.dbQueue.process('exportCustomEmojis', (job, done) => this.exportCustomEmojisProcessorService.process(job, done));
|
||||||
|
this.queueService.dbQueue.process('exportNotes', (job, done) => this.exportNotesProcessorService.process(job, done));
|
||||||
|
this.queueService.dbQueue.process('exportFavorites', (job, done) => this.exportFavoritesProcessorService.process(job, done));
|
||||||
|
this.queueService.dbQueue.process('exportFollowing', (job, done) => this.exportFollowingProcessorService.process(job, done));
|
||||||
|
this.queueService.dbQueue.process('exportMuting', (job, done) => this.exportMutingProcessorService.process(job, done));
|
||||||
|
this.queueService.dbQueue.process('exportBlocking', (job, done) => this.exportBlockingProcessorService.process(job, done));
|
||||||
|
this.queueService.dbQueue.process('exportUserLists', (job, done) => this.exportUserListsProcessorService.process(job, done));
|
||||||
|
this.queueService.dbQueue.process('exportAntennas', (job, done) => this.exportAntennasProcessorService.process(job, done));
|
||||||
|
this.queueService.dbQueue.process('importFollowing', (job, done) => this.importFollowingProcessorService.process(job, done));
|
||||||
|
this.queueService.dbQueue.process('importFollowingToDb', (job) => this.importFollowingProcessorService.processDb(job));
|
||||||
|
this.queueService.dbQueue.process('importMuting', (job, done) => this.importMutingProcessorService.process(job, done));
|
||||||
|
this.queueService.dbQueue.process('importBlocking', (job, done) => this.importBlockingProcessorService.process(job, done));
|
||||||
|
this.queueService.dbQueue.process('importBlockingToDb', (job) => this.importBlockingProcessorService.processDb(job));
|
||||||
|
this.queueService.dbQueue.process('importUserLists', (job, done) => this.importUserListsProcessorService.process(job, done));
|
||||||
|
this.queueService.dbQueue.process('importCustomEmojis', (job, done) => this.importCustomEmojisProcessorService.process(job, done));
|
||||||
|
this.queueService.dbQueue.process('importAntennas', (job, done) => this.importAntennasProcessorService.process(job, done));
|
||||||
|
this.queueService.dbQueue.process('deleteAccount', (job) => this.deleteAccountProcessorService.process(job));
|
||||||
|
|
||||||
|
this.queueService.objectStorageQueue.process('deleteFile', 16, (job) => this.deleteFileProcessorService.process(job));
|
||||||
|
this.queueService.objectStorageQueue.process('cleanRemoteFiles', 16, (job, done) => this.cleanRemoteFilesProcessorService.process(job, done));
|
||||||
|
|
||||||
|
{
|
||||||
|
const maxJobs = this.config.relashionshipJobConcurrency ?? 16;
|
||||||
|
this.queueService.relationshipQueue.process('follow', maxJobs, (job) => this.relationshipProcessorService.processFollow(job));
|
||||||
|
this.queueService.relationshipQueue.process('unfollow', maxJobs, (job) => this.relationshipProcessorService.processUnfollow(job));
|
||||||
|
this.queueService.relationshipQueue.process('block', maxJobs, (job) => this.relationshipProcessorService.processBlock(job));
|
||||||
|
this.queueService.relationshipQueue.process('unblock', maxJobs, (job) => this.relationshipProcessorService.processUnblock(job));
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
this.queueService.systemQueue.process('tickCharts', (job, done) => this.tickChartsProcessorService.process(job, done));
|
||||||
public async start(): Promise<void> {
|
this.queueService.systemQueue.process('resyncCharts', (job, done) => this.resyncChartsProcessorService.process(job, done));
|
||||||
await Promise.all([
|
this.queueService.systemQueue.process('cleanCharts', (job, done) => this.cleanChartsProcessorService.process(job, done));
|
||||||
this.systemQueueWorker.run(),
|
this.queueService.systemQueue.process('aggregateRetention', (job, done) => this.aggregateRetentionProcessorService.process(job, done));
|
||||||
this.dbQueueWorker.run(),
|
this.queueService.systemQueue.process('checkExpiredMutings', (job, done) => this.checkExpiredMutingsProcessorService.process(job, done));
|
||||||
this.deliverQueueWorker.run(),
|
this.queueService.systemQueue.process('clean', (job, done) => this.cleanProcessorService.process(job, done));
|
||||||
this.inboxQueueWorker.run(),
|
|
||||||
this.webhookDeliverQueueWorker.run(),
|
|
||||||
this.relationshipQueueWorker.run(),
|
|
||||||
this.objectStorageQueueWorker.run(),
|
|
||||||
this.endedPollNotificationQueueWorker.run(),
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async stop(): Promise<void> {
|
public async stop(): Promise<void> {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
this.systemQueueWorker.close(),
|
this.queueService.systemQueue.close(false),
|
||||||
this.dbQueueWorker.close(),
|
this.queueService.endedPollNotificationQueue.close(false),
|
||||||
this.deliverQueueWorker.close(),
|
this.queueService.deliverQueue.close(false),
|
||||||
this.inboxQueueWorker.close(),
|
this.queueService.inboxQueue.close(false),
|
||||||
this.webhookDeliverQueueWorker.close(),
|
this.queueService.dbQueue.close(false),
|
||||||
this.relationshipQueueWorker.close(),
|
this.queueService.relationshipQueue.close(false),
|
||||||
this.objectStorageQueueWorker.close(),
|
this.queueService.objectStorageQueue.close(false),
|
||||||
this.endedPollNotificationQueueWorker.close(),
|
this.queueService.webhookDeliverQueue.close(false),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
import { Config } from '@/config.js';
|
|
||||||
import type * as Bull from 'bullmq';
|
|
||||||
|
|
||||||
export const QUEUE = {
|
|
||||||
DELIVER: 'deliver',
|
|
||||||
INBOX: 'inbox',
|
|
||||||
SYSTEM: 'system',
|
|
||||||
ENDED_POLL_NOTIFICATION: 'endedPollNotification',
|
|
||||||
DB: 'db',
|
|
||||||
RELATIONSHIP: 'relationship',
|
|
||||||
OBJECT_STORAGE: 'objectStorage',
|
|
||||||
WEBHOOK_DELIVER: 'webhookDeliver',
|
|
||||||
};
|
|
||||||
|
|
||||||
export function baseQueueOptions(config: Config, queueName: typeof QUEUE[keyof typeof QUEUE]): Bull.QueueOptions {
|
|
||||||
return {
|
|
||||||
connection: {
|
|
||||||
port: config.redisForJobQueue.port,
|
|
||||||
host: config.redisForJobQueue.host,
|
|
||||||
family: config.redisForJobQueue.family == null ? 0 : config.redisForJobQueue.family,
|
|
||||||
password: config.redisForJobQueue.pass,
|
|
||||||
db: config.redisForJobQueue.db ?? 0,
|
|
||||||
},
|
|
||||||
prefix: config.redisForJobQueue.prefix ? `${config.redisForJobQueue.prefix}:queue:${queueName}` : `queue:${queueName}`,
|
|
||||||
};
|
|
||||||
}
|
|
15
packages/backend/src/queue/get-job-info.ts
Normal file
15
packages/backend/src/queue/get-job-info.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import Bull from 'bull';
|
||||||
|
|
||||||
|
export function getJobInfo(job: Bull.Job, increment = false) {
|
||||||
|
const age = Date.now() - job.timestamp;
|
||||||
|
|
||||||
|
const formated = age > 60000 ? `${Math.floor(age / 1000 / 60)}m`
|
||||||
|
: age > 10000 ? `${Math.floor(age / 1000)}s`
|
||||||
|
: `${age}ms`;
|
||||||
|
|
||||||
|
// onActiveとかonCompletedのattemptsMadeがなぜか0始まりなのでインクリメントする
|
||||||
|
const currentAttempts = job.attemptsMade + (increment ? 1 : 0);
|
||||||
|
const maxAttempts = job.opts ? job.opts.attempts : 0;
|
||||||
|
|
||||||
|
return `id=${job.id} attempts=${currentAttempts}/${maxAttempts} age=${formated}`;
|
||||||
|
}
|
|
@ -9,7 +9,7 @@ import { deepClone } from '@/misc/clone.js';
|
||||||
import { IdService } from '@/core/IdService.js';
|
import { IdService } from '@/core/IdService.js';
|
||||||
import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error.js';
|
import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error.js';
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type Bull from 'bull';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AggregateRetentionProcessorService {
|
export class AggregateRetentionProcessorService {
|
||||||
|
@ -32,7 +32,7 @@ export class AggregateRetentionProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async process(): Promise<void> {
|
public async process(job: Bull.Job<Record<string, unknown>>, done: () => void): Promise<void> {
|
||||||
this.logger.info('Aggregating retention...');
|
this.logger.info('Aggregating retention...');
|
||||||
|
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
|
@ -62,6 +62,7 @@ export class AggregateRetentionProcessorService {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (isDuplicateKeyValueError(err)) {
|
if (isDuplicateKeyValueError(err)) {
|
||||||
this.logger.succ('Skip because it has already been processed by another worker.');
|
this.logger.succ('Skip because it has already been processed by another worker.');
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
throw err;
|
throw err;
|
||||||
|
@ -87,5 +88,6 @@ export class AggregateRetentionProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.succ('Retention aggregated.');
|
this.logger.succ('Retention aggregated.');
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import type Logger from '@/logger.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { UserMutingService } from '@/core/UserMutingService.js';
|
import { UserMutingService } from '@/core/UserMutingService.js';
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type Bull from 'bull';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CheckExpiredMutingsProcessorService {
|
export class CheckExpiredMutingsProcessorService {
|
||||||
|
@ -27,7 +27,7 @@ export class CheckExpiredMutingsProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async process(): Promise<void> {
|
public async process(job: Bull.Job<Record<string, unknown>>, done: () => void): Promise<void> {
|
||||||
this.logger.info('Checking expired mutings...');
|
this.logger.info('Checking expired mutings...');
|
||||||
|
|
||||||
const expired = await this.mutingsRepository.createQueryBuilder('muting')
|
const expired = await this.mutingsRepository.createQueryBuilder('muting')
|
||||||
|
@ -41,5 +41,6 @@ export class CheckExpiredMutingsProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.succ('All expired mutings checked.');
|
this.logger.succ('All expired mutings checked.');
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ import PerUserDriveChart from '@/core/chart/charts/per-user-drive.js';
|
||||||
import ApRequestChart from '@/core/chart/charts/ap-request.js';
|
import ApRequestChart from '@/core/chart/charts/ap-request.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type Bull from 'bull';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CleanChartsProcessorService {
|
export class CleanChartsProcessorService {
|
||||||
|
@ -45,7 +45,7 @@ export class CleanChartsProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async process(): Promise<void> {
|
public async process(job: Bull.Job<Record<string, unknown>>, done: () => void): Promise<void> {
|
||||||
this.logger.info('Clean charts...');
|
this.logger.info('Clean charts...');
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
|
@ -64,5 +64,6 @@ export class CleanChartsProcessorService {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
this.logger.succ('All charts successfully cleaned.');
|
this.logger.succ('All charts successfully cleaned.');
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import type Logger from '@/logger.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { IdService } from '@/core/IdService.js';
|
import { IdService } from '@/core/IdService.js';
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type Bull from 'bull';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CleanProcessorService {
|
export class CleanProcessorService {
|
||||||
|
@ -36,7 +36,7 @@ export class CleanProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async process(): Promise<void> {
|
public async process(job: Bull.Job<Record<string, unknown>>, done: () => void): Promise<void> {
|
||||||
this.logger.info('Cleaning...');
|
this.logger.info('Cleaning...');
|
||||||
|
|
||||||
this.userIpsRepository.delete({
|
this.userIpsRepository.delete({
|
||||||
|
@ -72,5 +72,6 @@ export class CleanProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.succ('Cleaned.');
|
this.logger.succ('Cleaned.');
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,9 @@ import type { DriveFilesRepository } from '@/models/index.js';
|
||||||
import type { Config } from '@/config.js';
|
import type { Config } from '@/config.js';
|
||||||
import type Logger from '@/logger.js';
|
import type Logger from '@/logger.js';
|
||||||
import { DriveService } from '@/core/DriveService.js';
|
import { DriveService } from '@/core/DriveService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type Bull from 'bull';
|
||||||
|
import { bindThis } from '@/decorators.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CleanRemoteFilesProcessorService {
|
export class CleanRemoteFilesProcessorService {
|
||||||
|
@ -27,7 +27,7 @@ export class CleanRemoteFilesProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async process(job: Bull.Job<Record<string, unknown>>): Promise<void> {
|
public async process(job: Bull.Job<Record<string, unknown>>, done: () => void): Promise<void> {
|
||||||
this.logger.info('Deleting cached remote files...');
|
this.logger.info('Deleting cached remote files...');
|
||||||
|
|
||||||
let deletedCount = 0;
|
let deletedCount = 0;
|
||||||
|
@ -47,7 +47,7 @@ export class CleanRemoteFilesProcessorService {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (files.length === 0) {
|
if (files.length === 0) {
|
||||||
job.updateProgress(100);
|
job.progress(100);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,9 +62,10 @@ export class CleanRemoteFilesProcessorService {
|
||||||
isLink: false,
|
isLink: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
job.updateProgress(deletedCount / total);
|
job.progress(deletedCount / total);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.succ('All cached remote files has been deleted.');
|
this.logger.succ('All cached remote files has been deleted.');
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,10 +8,10 @@ import { DriveService } from '@/core/DriveService.js';
|
||||||
import type { DriveFile } from '@/models/entities/DriveFile.js';
|
import type { DriveFile } from '@/models/entities/DriveFile.js';
|
||||||
import type { Note } from '@/models/entities/Note.js';
|
import type { Note } from '@/models/entities/Note.js';
|
||||||
import { EmailService } from '@/core/EmailService.js';
|
import { EmailService } from '@/core/EmailService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type Bull from 'bull';
|
||||||
import type { DbUserDeleteJobData } from '../types.js';
|
import type { DbUserDeleteJobData } from '../types.js';
|
||||||
|
import { bindThis } from '@/decorators.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DeleteAccountProcessorService {
|
export class DeleteAccountProcessorService {
|
||||||
|
|
|
@ -5,10 +5,10 @@ import type { UsersRepository, DriveFilesRepository } from '@/models/index.js';
|
||||||
import type { Config } from '@/config.js';
|
import type { Config } from '@/config.js';
|
||||||
import type Logger from '@/logger.js';
|
import type Logger from '@/logger.js';
|
||||||
import { DriveService } from '@/core/DriveService.js';
|
import { DriveService } from '@/core/DriveService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type Bull from 'bull';
|
||||||
import type { DbJobDataWithUser } from '../types.js';
|
import type { DbJobDataWithUser } from '../types.js';
|
||||||
|
import { bindThis } from '@/decorators.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DeleteDriveFilesProcessorService {
|
export class DeleteDriveFilesProcessorService {
|
||||||
|
@ -31,11 +31,12 @@ export class DeleteDriveFilesProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async process(job: Bull.Job<DbJobDataWithUser>): Promise<void> {
|
public async process(job: Bull.Job<DbJobDataWithUser>, done: () => void): Promise<void> {
|
||||||
this.logger.info(`Deleting drive files of ${job.data.user.id} ...`);
|
this.logger.info(`Deleting drive files of ${job.data.user.id} ...`);
|
||||||
|
|
||||||
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +56,7 @@ export class DeleteDriveFilesProcessorService {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (files.length === 0) {
|
if (files.length === 0) {
|
||||||
job.updateProgress(100);
|
job.progress(100);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,9 +71,10 @@ export class DeleteDriveFilesProcessorService {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
job.updateProgress(deletedCount / total);
|
job.progress(deletedCount / total);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.succ(`All drive files (${deletedCount}) of ${user.id} has been deleted.`);
|
this.logger.succ(`All drive files (${deletedCount}) of ${user.id} has been deleted.`);
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,10 @@ import { DI } from '@/di-symbols.js';
|
||||||
import type { Config } from '@/config.js';
|
import type { Config } from '@/config.js';
|
||||||
import type Logger from '@/logger.js';
|
import type Logger from '@/logger.js';
|
||||||
import { DriveService } from '@/core/DriveService.js';
|
import { DriveService } from '@/core/DriveService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type Bull from 'bull';
|
||||||
import type { ObjectStorageFileJobData } from '../types.js';
|
import type { ObjectStorageFileJobData } from '../types.js';
|
||||||
|
import { bindThis } from '@/decorators.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class DeleteFileProcessorService {
|
export class DeleteFileProcessorService {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import * as Bull from 'bullmq';
|
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import type { DriveFilesRepository, InstancesRepository } from '@/models/index.js';
|
import type { DriveFilesRepository, InstancesRepository } from '@/models/index.js';
|
||||||
import type { Config } from '@/config.js';
|
import type { Config } from '@/config.js';
|
||||||
|
@ -17,6 +16,7 @@ import { StatusError } from '@/misc/status-error.js';
|
||||||
import { UtilityService } from '@/core/UtilityService.js';
|
import { UtilityService } from '@/core/UtilityService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
|
import type Bull from 'bull';
|
||||||
import type { DeliverJobData } from '../types.js';
|
import type { DeliverJobData } from '../types.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -121,9 +121,11 @@ export class DeliverProcessorService {
|
||||||
isSuspended: true,
|
isSuspended: true,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
throw new Bull.UnrecoverableError(`${host} is gone`);
|
return `${host} is gone`;
|
||||||
}
|
}
|
||||||
throw new Bull.UnrecoverableError(`${res.statusCode} ${res.statusMessage}`);
|
// HTTPステータスコード4xxはクライアントエラーであり、それはつまり
|
||||||
|
// 何回再送しても成功することはないということなのでエラーにはしないでおく
|
||||||
|
return `${res.statusCode} ${res.statusMessage}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5xx etc.
|
// 5xx etc.
|
||||||
|
|
|
@ -6,7 +6,7 @@ import type Logger from '@/logger.js';
|
||||||
import { NotificationService } from '@/core/NotificationService.js';
|
import { NotificationService } from '@/core/NotificationService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type Bull from 'bull';
|
||||||
import type { EndedPollNotificationJobData } from '../types.js';
|
import type { EndedPollNotificationJobData } from '../types.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -30,9 +30,10 @@ export class EndedPollNotificationProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async process(job: Bull.Job<EndedPollNotificationJobData>): Promise<void> {
|
public async process(job: Bull.Job<EndedPollNotificationJobData>, done: () => void): Promise<void> {
|
||||||
const note = await this.notesRepository.findOneBy({ id: job.data.noteId });
|
const note = await this.notesRepository.findOneBy({ id: job.data.noteId });
|
||||||
if (note == null || !note.hasPoll) {
|
if (note == null || !note.hasPoll) {
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,5 +51,7 @@ export class EndedPollNotificationProcessorService {
|
||||||
noteId: note.id,
|
noteId: note.id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { createTemp } from '@/misc/create-temp.js';
|
||||||
import { UtilityService } from '@/core/UtilityService.js';
|
import { UtilityService } from '@/core/UtilityService.js';
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type { DBExportAntennasData } from '../types.js';
|
import type { DBExportAntennasData } from '../types.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type Bull from 'bull';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ExportAntennasProcessorService {
|
export class ExportAntennasProcessorService {
|
||||||
|
@ -39,9 +39,10 @@ export class ExportAntennasProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async process(job: Bull.Job<DBExportAntennasData>): Promise<void> {
|
public async process(job: Bull.Job<DBExportAntennasData>, done: () => void): Promise<void> {
|
||||||
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const [path, cleanup] = await createTemp();
|
const [path, cleanup] = await createTemp();
|
||||||
|
@ -95,6 +96,7 @@ export class ExportAntennasProcessorService {
|
||||||
this.logger.succ('Exported to: ' + driveFile.id);
|
this.logger.succ('Exported to: ' + driveFile.id);
|
||||||
} finally {
|
} finally {
|
||||||
cleanup();
|
cleanup();
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,10 @@ import type Logger from '@/logger.js';
|
||||||
import { DriveService } from '@/core/DriveService.js';
|
import { DriveService } from '@/core/DriveService.js';
|
||||||
import { createTemp } from '@/misc/create-temp.js';
|
import { createTemp } from '@/misc/create-temp.js';
|
||||||
import { UtilityService } from '@/core/UtilityService.js';
|
import { UtilityService } from '@/core/UtilityService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type Bull from 'bull';
|
||||||
import type { DbJobDataWithUser } from '../types.js';
|
import type { DbJobDataWithUser } from '../types.js';
|
||||||
|
import { bindThis } from '@/decorators.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ExportBlockingProcessorService {
|
export class ExportBlockingProcessorService {
|
||||||
|
@ -36,11 +36,12 @@ export class ExportBlockingProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async process(job: Bull.Job<DbJobDataWithUser>): Promise<void> {
|
public async process(job: Bull.Job<DbJobDataWithUser>, done: () => void): Promise<void> {
|
||||||
this.logger.info(`Exporting blocking of ${job.data.user.id} ...`);
|
this.logger.info(`Exporting blocking of ${job.data.user.id} ...`);
|
||||||
|
|
||||||
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +69,7 @@ export class ExportBlockingProcessorService {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (blockings.length === 0) {
|
if (blockings.length === 0) {
|
||||||
job.updateProgress(100);
|
job.progress(100);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +99,7 @@ export class ExportBlockingProcessorService {
|
||||||
blockerId: user.id,
|
blockerId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
job.updateProgress(exportedCount / total);
|
job.progress(exportedCount / total);
|
||||||
}
|
}
|
||||||
|
|
||||||
stream.end();
|
stream.end();
|
||||||
|
@ -111,5 +112,7 @@ export class ExportBlockingProcessorService {
|
||||||
} finally {
|
} finally {
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import { createTemp, createTempDir } from '@/misc/create-temp.js';
|
||||||
import { DownloadService } from '@/core/DownloadService.js';
|
import { DownloadService } from '@/core/DownloadService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type Bull from 'bull';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ExportCustomEmojisProcessorService {
|
export class ExportCustomEmojisProcessorService {
|
||||||
|
@ -37,11 +37,12 @@ export class ExportCustomEmojisProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async process(job: Bull.Job): Promise<void> {
|
public async process(job: Bull.Job, done: () => void): Promise<void> {
|
||||||
this.logger.info('Exporting custom emojis ...');
|
this.logger.info('Exporting custom emojis ...');
|
||||||
|
|
||||||
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +117,6 @@ export class ExportCustomEmojisProcessorService {
|
||||||
metaStream.end();
|
metaStream.end();
|
||||||
|
|
||||||
// Create archive
|
// Create archive
|
||||||
await new Promise<void>(async (resolve) => {
|
|
||||||
const [archivePath, archiveCleanup] = await createTemp();
|
const [archivePath, archiveCleanup] = await createTemp();
|
||||||
const archiveStream = fs.createWriteStream(archivePath);
|
const archiveStream = fs.createWriteStream(archivePath);
|
||||||
const archive = archiver('zip', {
|
const archive = archiver('zip', {
|
||||||
|
@ -131,11 +131,10 @@ export class ExportCustomEmojisProcessorService {
|
||||||
this.logger.succ(`Exported to: ${driveFile.id}`);
|
this.logger.succ(`Exported to: ${driveFile.id}`);
|
||||||
cleanup();
|
cleanup();
|
||||||
archiveCleanup();
|
archiveCleanup();
|
||||||
resolve();
|
done();
|
||||||
});
|
});
|
||||||
archive.pipe(archiveStream);
|
archive.pipe(archiveStream);
|
||||||
archive.directory(path, false);
|
archive.directory(path, false);
|
||||||
archive.finalize();
|
archive.finalize();
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import type { Poll } from '@/models/entities/Poll.js';
|
||||||
import type { Note } from '@/models/entities/Note.js';
|
import type { Note } from '@/models/entities/Note.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type Bull from 'bull';
|
||||||
import type { DbJobDataWithUser } from '../types.js';
|
import type { DbJobDataWithUser } from '../types.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -42,11 +42,12 @@ export class ExportFavoritesProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async process(job: Bull.Job<DbJobDataWithUser>): Promise<void> {
|
public async process(job: Bull.Job<DbJobDataWithUser>, done: () => void): Promise<void> {
|
||||||
this.logger.info(`Exporting favorites of ${job.data.user.id} ...`);
|
this.logger.info(`Exporting favorites of ${job.data.user.id} ...`);
|
||||||
|
|
||||||
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +91,7 @@ export class ExportFavoritesProcessorService {
|
||||||
}) as (NoteFavorite & { note: Note & { user: User } })[];
|
}) as (NoteFavorite & { note: Note & { user: User } })[];
|
||||||
|
|
||||||
if (favorites.length === 0) {
|
if (favorites.length === 0) {
|
||||||
job.updateProgress(100);
|
job.progress(100);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +112,7 @@ export class ExportFavoritesProcessorService {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
job.updateProgress(exportedFavoritesCount / total);
|
job.progress(exportedFavoritesCount / total);
|
||||||
}
|
}
|
||||||
|
|
||||||
await write(']');
|
await write(']');
|
||||||
|
@ -126,6 +127,8 @@ export class ExportFavoritesProcessorService {
|
||||||
} finally {
|
} finally {
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,10 +10,10 @@ import { DriveService } from '@/core/DriveService.js';
|
||||||
import { createTemp } from '@/misc/create-temp.js';
|
import { createTemp } from '@/misc/create-temp.js';
|
||||||
import type { Following } from '@/models/entities/Following.js';
|
import type { Following } from '@/models/entities/Following.js';
|
||||||
import { UtilityService } from '@/core/UtilityService.js';
|
import { UtilityService } from '@/core/UtilityService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type Bull from 'bull';
|
||||||
import type { DbExportFollowingData } from '../types.js';
|
import type { DbExportFollowingData } from '../types.js';
|
||||||
|
import { bindThis } from '@/decorators.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ExportFollowingProcessorService {
|
export class ExportFollowingProcessorService {
|
||||||
|
@ -40,11 +40,12 @@ export class ExportFollowingProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async process(job: Bull.Job<DbExportFollowingData>): Promise<void> {
|
public async process(job: Bull.Job<DbExportFollowingData>, done: () => void): Promise<void> {
|
||||||
this.logger.info(`Exporting following of ${job.data.user.id} ...`);
|
this.logger.info(`Exporting following of ${job.data.user.id} ...`);
|
||||||
|
|
||||||
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,5 +116,7 @@ export class ExportFollowingProcessorService {
|
||||||
} finally {
|
} finally {
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,10 @@ import type Logger from '@/logger.js';
|
||||||
import { DriveService } from '@/core/DriveService.js';
|
import { DriveService } from '@/core/DriveService.js';
|
||||||
import { createTemp } from '@/misc/create-temp.js';
|
import { createTemp } from '@/misc/create-temp.js';
|
||||||
import { UtilityService } from '@/core/UtilityService.js';
|
import { UtilityService } from '@/core/UtilityService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type Bull from 'bull';
|
||||||
import type { DbJobDataWithUser } from '../types.js';
|
import type { DbJobDataWithUser } from '../types.js';
|
||||||
|
import { bindThis } from '@/decorators.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ExportMutingProcessorService {
|
export class ExportMutingProcessorService {
|
||||||
|
@ -39,11 +39,12 @@ export class ExportMutingProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async process(job: Bull.Job<DbJobDataWithUser>): Promise<void> {
|
public async process(job: Bull.Job<DbJobDataWithUser>, done: () => void): Promise<void> {
|
||||||
this.logger.info(`Exporting muting of ${job.data.user.id} ...`);
|
this.logger.info(`Exporting muting of ${job.data.user.id} ...`);
|
||||||
|
|
||||||
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +73,7 @@ export class ExportMutingProcessorService {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (mutes.length === 0) {
|
if (mutes.length === 0) {
|
||||||
job.updateProgress(100);
|
job.progress(100);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +103,7 @@ export class ExportMutingProcessorService {
|
||||||
muterId: user.id,
|
muterId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
job.updateProgress(exportedCount / total);
|
job.progress(exportedCount / total);
|
||||||
}
|
}
|
||||||
|
|
||||||
stream.end();
|
stream.end();
|
||||||
|
@ -115,5 +116,7 @@ export class ExportMutingProcessorService {
|
||||||
} finally {
|
} finally {
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import type { Poll } from '@/models/entities/Poll.js';
|
||||||
import type { Note } from '@/models/entities/Note.js';
|
import type { Note } from '@/models/entities/Note.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type Bull from 'bull';
|
||||||
import type { DbJobDataWithUser } from '../types.js';
|
import type { DbJobDataWithUser } from '../types.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -39,11 +39,12 @@ export class ExportNotesProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async process(job: Bull.Job<DbJobDataWithUser>): Promise<void> {
|
public async process(job: Bull.Job<DbJobDataWithUser>, done: () => void): Promise<void> {
|
||||||
this.logger.info(`Exporting notes of ${job.data.user.id} ...`);
|
this.logger.info(`Exporting notes of ${job.data.user.id} ...`);
|
||||||
|
|
||||||
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +87,7 @@ export class ExportNotesProcessorService {
|
||||||
}) as Note[];
|
}) as Note[];
|
||||||
|
|
||||||
if (notes.length === 0) {
|
if (notes.length === 0) {
|
||||||
job.updateProgress(100);
|
job.progress(100);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +108,7 @@ export class ExportNotesProcessorService {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
job.updateProgress(exportedNotesCount / total);
|
job.progress(exportedNotesCount / total);
|
||||||
}
|
}
|
||||||
|
|
||||||
await write(']');
|
await write(']');
|
||||||
|
@ -122,6 +123,8 @@ export class ExportNotesProcessorService {
|
||||||
} finally {
|
} finally {
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,10 @@ import type Logger from '@/logger.js';
|
||||||
import { DriveService } from '@/core/DriveService.js';
|
import { DriveService } from '@/core/DriveService.js';
|
||||||
import { createTemp } from '@/misc/create-temp.js';
|
import { createTemp } from '@/misc/create-temp.js';
|
||||||
import { UtilityService } from '@/core/UtilityService.js';
|
import { UtilityService } from '@/core/UtilityService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type Bull from 'bull';
|
||||||
import type { DbJobDataWithUser } from '../types.js';
|
import type { DbJobDataWithUser } from '../types.js';
|
||||||
|
import { bindThis } from '@/decorators.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ExportUserListsProcessorService {
|
export class ExportUserListsProcessorService {
|
||||||
|
@ -39,11 +39,12 @@ export class ExportUserListsProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async process(job: Bull.Job<DbJobDataWithUser>): Promise<void> {
|
public async process(job: Bull.Job<DbJobDataWithUser>, done: () => void): Promise<void> {
|
||||||
this.logger.info(`Exporting user lists of ${job.data.user.id} ...`);
|
this.logger.info(`Exporting user lists of ${job.data.user.id} ...`);
|
||||||
|
|
||||||
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,5 +92,7 @@ export class ExportUserListsProcessorService {
|
||||||
} finally {
|
} finally {
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { DI } from '@/di-symbols.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import { DBAntennaImportJobData } from '../types.js';
|
import { DBAntennaImportJobData } from '../types.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type Bull from 'bull';
|
||||||
|
|
||||||
const validate = new Ajv().compile({
|
const validate = new Ajv().compile({
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
@ -59,7 +59,7 @@ export class ImportAntennasProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async process(job: Bull.Job<DBAntennaImportJobData>): Promise<void> {
|
public async process(job: Bull.Job<DBAntennaImportJobData>, done: () => void): Promise<void> {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
try {
|
try {
|
||||||
for (const antenna of job.data.antenna) {
|
for (const antenna of job.data.antenna) {
|
||||||
|
@ -89,6 +89,8 @@ export class ImportAntennasProcessorService {
|
||||||
}
|
}
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
this.logger.error(err);
|
this.logger.error(err);
|
||||||
|
} finally {
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,11 @@ import * as Acct from '@/misc/acct.js';
|
||||||
import { RemoteUserResolveService } from '@/core/RemoteUserResolveService.js';
|
import { RemoteUserResolveService } from '@/core/RemoteUserResolveService.js';
|
||||||
import { DownloadService } from '@/core/DownloadService.js';
|
import { DownloadService } from '@/core/DownloadService.js';
|
||||||
import { UtilityService } from '@/core/UtilityService.js';
|
import { UtilityService } from '@/core/UtilityService.js';
|
||||||
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
|
import type Bull from 'bull';
|
||||||
|
import type { DbUserImportJobData, DbUserImportToDbJobData } from '../types.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { QueueService } from '@/core/QueueService.js';
|
import { QueueService } from '@/core/QueueService.js';
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
|
||||||
import type * as Bull from 'bullmq';
|
|
||||||
import type { DbUserImportJobData, DbUserImportToDbJobData } from '../types.js';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ImportBlockingProcessorService {
|
export class ImportBlockingProcessorService {
|
||||||
|
@ -34,11 +34,12 @@ export class ImportBlockingProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async process(job: Bull.Job<DbUserImportJobData>): Promise<void> {
|
public async process(job: Bull.Job<DbUserImportJobData>, done: () => void): Promise<void> {
|
||||||
this.logger.info(`Importing blocking of ${job.data.user.id} ...`);
|
this.logger.info(`Importing blocking of ${job.data.user.id} ...`);
|
||||||
|
|
||||||
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +47,7 @@ export class ImportBlockingProcessorService {
|
||||||
id: job.data.fileId,
|
id: job.data.fileId,
|
||||||
});
|
});
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +56,7 @@ export class ImportBlockingProcessorService {
|
||||||
this.queueService.createImportBlockingToDbJob({ id: user.id }, targets);
|
this.queueService.createImportBlockingToDbJob({ id: user.id }, targets);
|
||||||
|
|
||||||
this.logger.succ('Import jobs created');
|
this.logger.succ('Import jobs created');
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { DriveService } from '@/core/DriveService.js';
|
||||||
import { DownloadService } from '@/core/DownloadService.js';
|
import { DownloadService } from '@/core/DownloadService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type Bull from 'bull';
|
||||||
import type { DbUserImportJobData } from '../types.js';
|
import type { DbUserImportJobData } from '../types.js';
|
||||||
|
|
||||||
// TODO: 名前衝突時の動作を選べるようにする
|
// TODO: 名前衝突時の動作を選べるようにする
|
||||||
|
@ -45,13 +45,14 @@ export class ImportCustomEmojisProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async process(job: Bull.Job<DbUserImportJobData>): Promise<void> {
|
public async process(job: Bull.Job<DbUserImportJobData>, done: () => void): Promise<void> {
|
||||||
this.logger.info('Importing custom emojis ...');
|
this.logger.info('Importing custom emojis ...');
|
||||||
|
|
||||||
const file = await this.driveFilesRepository.findOneBy({
|
const file = await this.driveFilesRepository.findOneBy({
|
||||||
id: job.data.fileId,
|
id: job.data.fileId,
|
||||||
});
|
});
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +116,7 @@ export class ImportCustomEmojisProcessorService {
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
this.logger.succ('Imported');
|
this.logger.succ('Imported');
|
||||||
|
done();
|
||||||
});
|
});
|
||||||
unzipStream.pipe(extractor);
|
unzipStream.pipe(extractor);
|
||||||
this.logger.succ(`Unzipping to ${outputPath}`);
|
this.logger.succ(`Unzipping to ${outputPath}`);
|
||||||
|
|
|
@ -7,11 +7,11 @@ import * as Acct from '@/misc/acct.js';
|
||||||
import { RemoteUserResolveService } from '@/core/RemoteUserResolveService.js';
|
import { RemoteUserResolveService } from '@/core/RemoteUserResolveService.js';
|
||||||
import { DownloadService } from '@/core/DownloadService.js';
|
import { DownloadService } from '@/core/DownloadService.js';
|
||||||
import { UtilityService } from '@/core/UtilityService.js';
|
import { UtilityService } from '@/core/UtilityService.js';
|
||||||
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
|
import type Bull from 'bull';
|
||||||
|
import type { DbUserImportJobData, DbUserImportToDbJobData } from '../types.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { QueueService } from '@/core/QueueService.js';
|
import { QueueService } from '@/core/QueueService.js';
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
|
||||||
import type * as Bull from 'bullmq';
|
|
||||||
import type { DbUserImportJobData, DbUserImportToDbJobData } from '../types.js';
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ImportFollowingProcessorService {
|
export class ImportFollowingProcessorService {
|
||||||
|
@ -34,11 +34,12 @@ export class ImportFollowingProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async process(job: Bull.Job<DbUserImportJobData>): Promise<void> {
|
public async process(job: Bull.Job<DbUserImportJobData>, done: () => void): Promise<void> {
|
||||||
this.logger.info(`Importing following of ${job.data.user.id} ...`);
|
this.logger.info(`Importing following of ${job.data.user.id} ...`);
|
||||||
|
|
||||||
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +47,7 @@ export class ImportFollowingProcessorService {
|
||||||
id: job.data.fileId,
|
id: job.data.fileId,
|
||||||
});
|
});
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +56,7 @@ export class ImportFollowingProcessorService {
|
||||||
this.queueService.createImportFollowingToDbJob({ id: user.id }, targets);
|
this.queueService.createImportFollowingToDbJob({ id: user.id }, targets);
|
||||||
|
|
||||||
this.logger.succ('Import jobs created');
|
this.logger.succ('Import jobs created');
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
|
|
|
@ -9,10 +9,10 @@ import { RemoteUserResolveService } from '@/core/RemoteUserResolveService.js';
|
||||||
import { DownloadService } from '@/core/DownloadService.js';
|
import { DownloadService } from '@/core/DownloadService.js';
|
||||||
import { UserMutingService } from '@/core/UserMutingService.js';
|
import { UserMutingService } from '@/core/UserMutingService.js';
|
||||||
import { UtilityService } from '@/core/UtilityService.js';
|
import { UtilityService } from '@/core/UtilityService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type Bull from 'bull';
|
||||||
import type { DbUserImportJobData } from '../types.js';
|
import type { DbUserImportJobData } from '../types.js';
|
||||||
|
import { bindThis } from '@/decorators.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ImportMutingProcessorService {
|
export class ImportMutingProcessorService {
|
||||||
|
@ -38,11 +38,12 @@ export class ImportMutingProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async process(job: Bull.Job<DbUserImportJobData>): Promise<void> {
|
public async process(job: Bull.Job<DbUserImportJobData>, done: () => void): Promise<void> {
|
||||||
this.logger.info(`Importing muting of ${job.data.user.id} ...`);
|
this.logger.info(`Importing muting of ${job.data.user.id} ...`);
|
||||||
|
|
||||||
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +51,7 @@ export class ImportMutingProcessorService {
|
||||||
id: job.data.fileId,
|
id: job.data.fileId,
|
||||||
});
|
});
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,5 +98,6 @@ export class ImportMutingProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.succ('Imported');
|
this.logger.succ('Imported');
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { IdService } from '@/core/IdService.js';
|
||||||
import { UtilityService } from '@/core/UtilityService.js';
|
import { UtilityService } from '@/core/UtilityService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type Bull from 'bull';
|
||||||
import type { DbUserImportJobData } from '../types.js';
|
import type { DbUserImportJobData } from '../types.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -46,11 +46,12 @@ export class ImportUserListsProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async process(job: Bull.Job<DbUserImportJobData>): Promise<void> {
|
public async process(job: Bull.Job<DbUserImportJobData>, done: () => void): Promise<void> {
|
||||||
this.logger.info(`Importing user lists of ${job.data.user.id} ...`);
|
this.logger.info(`Importing user lists of ${job.data.user.id} ...`);
|
||||||
|
|
||||||
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
const user = await this.usersRepository.findOneBy({ id: job.data.user.id });
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +59,7 @@ export class ImportUserListsProcessorService {
|
||||||
id: job.data.fileId,
|
id: job.data.fileId,
|
||||||
});
|
});
|
||||||
if (file == null) {
|
if (file == null) {
|
||||||
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,5 +109,6 @@ export class ImportUserListsProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.succ('Imported');
|
this.logger.succ('Imported');
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { URL } from 'node:url';
|
import { URL } from 'node:url';
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import httpSignature from '@peertube/http-signature';
|
import httpSignature from '@peertube/http-signature';
|
||||||
import * as Bull from 'bullmq';
|
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
|
import type { InstancesRepository, DriveFilesRepository } from '@/models/index.js';
|
||||||
import type { Config } from '@/config.js';
|
import type { Config } from '@/config.js';
|
||||||
import type Logger from '@/logger.js';
|
import type Logger from '@/logger.js';
|
||||||
import { MetaService } from '@/core/MetaService.js';
|
import { MetaService } from '@/core/MetaService.js';
|
||||||
|
@ -23,8 +23,10 @@ import { LdSignatureService } from '@/core/activitypub/LdSignatureService.js';
|
||||||
import { ApInboxService } from '@/core/activitypub/ApInboxService.js';
|
import { ApInboxService } from '@/core/activitypub/ApInboxService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
|
import type Bull from 'bull';
|
||||||
import type { InboxJobData } from '../types.js';
|
import type { InboxJobData } from '../types.js';
|
||||||
|
|
||||||
|
// ユーザーのinboxにアクティビティが届いた時の処理
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class InboxProcessorService {
|
export class InboxProcessorService {
|
||||||
private logger: Logger;
|
private logger: Logger;
|
||||||
|
@ -33,6 +35,12 @@ export class InboxProcessorService {
|
||||||
@Inject(DI.config)
|
@Inject(DI.config)
|
||||||
private config: Config,
|
private config: Config,
|
||||||
|
|
||||||
|
@Inject(DI.instancesRepository)
|
||||||
|
private instancesRepository: InstancesRepository,
|
||||||
|
|
||||||
|
@Inject(DI.driveFilesRepository)
|
||||||
|
private driveFilesRepository: DriveFilesRepository,
|
||||||
|
|
||||||
private utilityService: UtilityService,
|
private utilityService: UtilityService,
|
||||||
private metaService: MetaService,
|
private metaService: MetaService,
|
||||||
private apInboxService: ApInboxService,
|
private apInboxService: ApInboxService,
|
||||||
|
@ -88,7 +96,7 @@ export class InboxProcessorService {
|
||||||
// 対象が4xxならスキップ
|
// 対象が4xxならスキップ
|
||||||
if (err instanceof StatusError) {
|
if (err instanceof StatusError) {
|
||||||
if (err.isClientError) {
|
if (err.isClientError) {
|
||||||
throw new Bull.UnrecoverableError(`skip: Ignored deleted actors on both ends ${activity.actor} - ${err.statusCode}`);
|
return `skip: Ignored deleted actors on both ends ${activity.actor} - ${err.statusCode}`;
|
||||||
}
|
}
|
||||||
throw new Error(`Error in actor ${activity.actor} - ${err.statusCode ?? err}`);
|
throw new Error(`Error in actor ${activity.actor} - ${err.statusCode ?? err}`);
|
||||||
}
|
}
|
||||||
|
@ -97,12 +105,12 @@ export class InboxProcessorService {
|
||||||
|
|
||||||
// それでもわからなければ終了
|
// それでもわからなければ終了
|
||||||
if (authUser == null) {
|
if (authUser == null) {
|
||||||
throw new Bull.UnrecoverableError('skip: failed to resolve user');
|
return 'skip: failed to resolve user';
|
||||||
}
|
}
|
||||||
|
|
||||||
// publicKey がなくても終了
|
// publicKey がなくても終了
|
||||||
if (authUser.key == null) {
|
if (authUser.key == null) {
|
||||||
throw new Bull.UnrecoverableError('skip: failed to resolve user publicKey');
|
return 'skip: failed to resolve user publicKey';
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTP-Signatureの検証
|
// HTTP-Signatureの検証
|
||||||
|
@ -113,7 +121,7 @@ export class InboxProcessorService {
|
||||||
// 一致しなくても、でもLD-Signatureがありそうならそっちも見る
|
// 一致しなくても、でもLD-Signatureがありそうならそっちも見る
|
||||||
if (activity.signature) {
|
if (activity.signature) {
|
||||||
if (activity.signature.type !== 'RsaSignature2017') {
|
if (activity.signature.type !== 'RsaSignature2017') {
|
||||||
throw new Bull.UnrecoverableError(`skip: unsupported LD-signature type ${activity.signature.type}`);
|
return `skip: unsupported LD-signature type ${activity.signature.type}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// activity.signature.creator: https://example.oom/users/user#main-key
|
// activity.signature.creator: https://example.oom/users/user#main-key
|
||||||
|
@ -126,32 +134,32 @@ export class InboxProcessorService {
|
||||||
// keyIdからLD-Signatureのユーザーを取得
|
// keyIdからLD-Signatureのユーザーを取得
|
||||||
authUser = await this.apDbResolverService.getAuthUserFromKeyId(activity.signature.creator);
|
authUser = await this.apDbResolverService.getAuthUserFromKeyId(activity.signature.creator);
|
||||||
if (authUser == null) {
|
if (authUser == null) {
|
||||||
throw new Bull.UnrecoverableError('skip: LD-Signatureのユーザーが取得できませんでした');
|
return 'skip: LD-Signatureのユーザーが取得できませんでした';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (authUser.key == null) {
|
if (authUser.key == null) {
|
||||||
throw new Bull.UnrecoverableError('skip: LD-SignatureのユーザーはpublicKeyを持っていませんでした');
|
return 'skip: LD-SignatureのユーザーはpublicKeyを持っていませんでした';
|
||||||
}
|
}
|
||||||
|
|
||||||
// LD-Signature検証
|
// LD-Signature検証
|
||||||
const ldSignature = this.ldSignatureService.use();
|
const ldSignature = this.ldSignatureService.use();
|
||||||
const verified = await ldSignature.verifyRsaSignature2017(activity, authUser.key.keyPem).catch(() => false);
|
const verified = await ldSignature.verifyRsaSignature2017(activity, authUser.key.keyPem).catch(() => false);
|
||||||
if (!verified) {
|
if (!verified) {
|
||||||
throw new Bull.UnrecoverableError('skip: LD-Signatureの検証に失敗しました');
|
return 'skip: LD-Signatureの検証に失敗しました';
|
||||||
}
|
}
|
||||||
|
|
||||||
// もう一度actorチェック
|
// もう一度actorチェック
|
||||||
if (authUser.user.uri !== activity.actor) {
|
if (authUser.user.uri !== activity.actor) {
|
||||||
throw new Bull.UnrecoverableError(`skip: LD-Signature user(${authUser.user.uri}) !== activity.actor(${activity.actor})`);
|
return `skip: LD-Signature user(${authUser.user.uri}) !== activity.actor(${activity.actor})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ブロックしてたら中断
|
// ブロックしてたら中断
|
||||||
const ldHost = this.utilityService.extractDbHost(authUser.user.uri);
|
const ldHost = this.utilityService.extractDbHost(authUser.user.uri);
|
||||||
if (this.utilityService.isBlockedHost(meta.blockedHosts, ldHost)) {
|
if (this.utilityService.isBlockedHost(meta.blockedHosts, ldHost)) {
|
||||||
throw new Bull.UnrecoverableError(`Blocked request: ${ldHost}`);
|
return `Blocked request: ${ldHost}`;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Bull.UnrecoverableError(`skip: http-signature verification failed and no LD-Signature. keyId=${signature.keyId}`);
|
return `skip: http-signature verification failed and no LD-Signature. keyId=${signature.keyId}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +168,7 @@ export class InboxProcessorService {
|
||||||
const signerHost = this.utilityService.extractDbHost(authUser.user.uri!);
|
const signerHost = this.utilityService.extractDbHost(authUser.user.uri!);
|
||||||
const activityIdHost = this.utilityService.extractDbHost(activity.id);
|
const activityIdHost = this.utilityService.extractDbHost(activity.id);
|
||||||
if (signerHost !== activityIdHost) {
|
if (signerHost !== activityIdHost) {
|
||||||
throw new Bull.UnrecoverableError(`skip: signerHost(${signerHost}) !== activity.id host(${activityIdHost}`);
|
return `skip: signerHost(${signerHost}) !== activity.id host(${activityIdHost}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import type * as Bull from 'bullmq';
|
import type Bull from 'bull';
|
||||||
|
|
||||||
import { UserFollowingService } from '@/core/UserFollowingService.js';
|
import { UserFollowingService } from '@/core/UserFollowingService.js';
|
||||||
import { UserBlockingService } from '@/core/UserBlockingService.js';
|
import { UserBlockingService } from '@/core/UserBlockingService.js';
|
||||||
|
|
|
@ -15,7 +15,7 @@ import PerUserDriveChart from '@/core/chart/charts/per-user-drive.js';
|
||||||
import ApRequestChart from '@/core/chart/charts/ap-request.js';
|
import ApRequestChart from '@/core/chart/charts/ap-request.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type Bull from 'bull';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ResyncChartsProcessorService {
|
export class ResyncChartsProcessorService {
|
||||||
|
@ -43,7 +43,7 @@ export class ResyncChartsProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async process(): Promise<void> {
|
public async process(job: Bull.Job<Record<string, unknown>>, done: () => void): Promise<void> {
|
||||||
this.logger.info('Resync charts...');
|
this.logger.info('Resync charts...');
|
||||||
|
|
||||||
// TODO: ユーザーごとのチャートも更新する
|
// TODO: ユーザーごとのチャートも更新する
|
||||||
|
@ -55,5 +55,6 @@ export class ResyncChartsProcessorService {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
this.logger.succ('All charts successfully resynced.');
|
this.logger.succ('All charts successfully resynced.');
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ import PerUserDriveChart from '@/core/chart/charts/per-user-drive.js';
|
||||||
import ApRequestChart from '@/core/chart/charts/ap-request.js';
|
import ApRequestChart from '@/core/chart/charts/ap-request.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
import type * as Bull from 'bullmq';
|
import type Bull from 'bull';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TickChartsProcessorService {
|
export class TickChartsProcessorService {
|
||||||
|
@ -45,7 +45,7 @@ export class TickChartsProcessorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@bindThis
|
@bindThis
|
||||||
public async process(): Promise<void> {
|
public async process(job: Bull.Job<Record<string, unknown>>, done: () => void): Promise<void> {
|
||||||
this.logger.info('Tick charts...');
|
this.logger.info('Tick charts...');
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
|
@ -64,5 +64,6 @@ export class TickChartsProcessorService {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
this.logger.succ('All charts successfully ticked.');
|
this.logger.succ('All charts successfully ticked.');
|
||||||
|
done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import * as Bull from 'bullmq';
|
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import type { WebhooksRepository } from '@/models/index.js';
|
import type { WebhooksRepository } from '@/models/index.js';
|
||||||
import type { Config } from '@/config.js';
|
import type { Config } from '@/config.js';
|
||||||
|
@ -8,6 +7,7 @@ import { HttpRequestService } from '@/core/HttpRequestService.js';
|
||||||
import { StatusError } from '@/misc/status-error.js';
|
import { StatusError } from '@/misc/status-error.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import { QueueLoggerService } from '../QueueLoggerService.js';
|
import { QueueLoggerService } from '../QueueLoggerService.js';
|
||||||
|
import type Bull from 'bull';
|
||||||
import type { WebhookDeliverJobData } from '../types.js';
|
import type { WebhookDeliverJobData } from '../types.js';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -66,7 +66,7 @@ export class WebhookDeliverProcessorService {
|
||||||
if (res instanceof StatusError) {
|
if (res instanceof StatusError) {
|
||||||
// 4xx
|
// 4xx
|
||||||
if (res.isClientError) {
|
if (res.isClientError) {
|
||||||
throw new Bull.UnrecoverableError(`${res.statusCode} ${res.statusMessage}`);
|
return `${res.statusCode} ${res.statusMessage}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5xx etc.
|
// 5xx etc.
|
||||||
|
|
|
@ -5,8 +5,7 @@ const dateTimeIntervals = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export function dateUTC(time: number[]): Date {
|
export function dateUTC(time: number[]): Date {
|
||||||
const d =
|
const d = time.length === 2 ? Date.UTC(time[0], time[1])
|
||||||
time.length === 2 ? Date.UTC(time[0], time[1])
|
|
||||||
: time.length === 3 ? Date.UTC(time[0], time[1], time[2])
|
: time.length === 3 ? Date.UTC(time[0], time[1], time[2])
|
||||||
: time.length === 4 ? Date.UTC(time[0], time[1], time[2], time[3])
|
: time.length === 4 ? Date.UTC(time[0], time[1], time[2], time[3])
|
||||||
: time.length === 5 ? Date.UTC(time[0], time[1], time[2], time[3], time[4])
|
: time.length === 5 ? Date.UTC(time[0], time[1], time[2], time[3], time[4])
|
||||||
|
|
173
pnpm-lock.yaml
173
pnpm-lock.yaml
|
@ -149,9 +149,9 @@ importers:
|
||||||
blurhash:
|
blurhash:
|
||||||
specifier: 2.0.5
|
specifier: 2.0.5
|
||||||
version: 2.0.5
|
version: 2.0.5
|
||||||
bullmq:
|
bull:
|
||||||
specifier: 3.15.0
|
specifier: 4.10.4
|
||||||
version: 3.15.0
|
version: 4.10.4
|
||||||
cacheable-lookup:
|
cacheable-lookup:
|
||||||
specifier: 6.1.0
|
specifier: 6.1.0
|
||||||
version: 6.1.0
|
version: 6.1.0
|
||||||
|
@ -2113,7 +2113,7 @@ packages:
|
||||||
'@babel/traverse': 7.22.4
|
'@babel/traverse': 7.22.4
|
||||||
'@babel/types': 7.22.4
|
'@babel/types': 7.22.4
|
||||||
convert-source-map: 1.9.0
|
convert-source-map: 1.9.0
|
||||||
debug: 4.3.4(supports-color@8.1.1)
|
debug: 4.3.4
|
||||||
gensync: 1.0.0-beta.2
|
gensync: 1.0.0-beta.2
|
||||||
json5: 2.2.3
|
json5: 2.2.3
|
||||||
semver: 6.3.0
|
semver: 6.3.0
|
||||||
|
@ -2136,7 +2136,7 @@ packages:
|
||||||
'@babel/traverse': 7.22.4
|
'@babel/traverse': 7.22.4
|
||||||
'@babel/types': 7.22.4
|
'@babel/types': 7.22.4
|
||||||
convert-source-map: 1.9.0
|
convert-source-map: 1.9.0
|
||||||
debug: 4.3.4(supports-color@8.1.1)
|
debug: 4.3.4
|
||||||
gensync: 1.0.0-beta.2
|
gensync: 1.0.0-beta.2
|
||||||
json5: 2.2.3
|
json5: 2.2.3
|
||||||
semver: 6.3.0
|
semver: 6.3.0
|
||||||
|
@ -4322,7 +4322,7 @@ packages:
|
||||||
'@babel/helper-split-export-declaration': 7.18.6
|
'@babel/helper-split-export-declaration': 7.18.6
|
||||||
'@babel/parser': 7.22.4
|
'@babel/parser': 7.22.4
|
||||||
'@babel/types': 7.22.4
|
'@babel/types': 7.22.4
|
||||||
debug: 4.3.4(supports-color@8.1.1)
|
debug: 4.3.4
|
||||||
globals: 11.12.0
|
globals: 11.12.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
@ -4751,7 +4751,7 @@ packages:
|
||||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
dependencies:
|
dependencies:
|
||||||
ajv: 6.12.6
|
ajv: 6.12.6
|
||||||
debug: 4.3.4(supports-color@8.1.1)
|
debug: 4.3.4
|
||||||
espree: 9.5.2
|
espree: 9.5.2
|
||||||
globals: 13.19.0
|
globals: 13.19.0
|
||||||
ignore: 5.2.4
|
ignore: 5.2.4
|
||||||
|
@ -4916,7 +4916,7 @@ packages:
|
||||||
engines: {node: '>=10.10.0'}
|
engines: {node: '>=10.10.0'}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@humanwhocodes/object-schema': 1.2.1
|
'@humanwhocodes/object-schema': 1.2.1
|
||||||
debug: 4.3.4(supports-color@8.1.1)
|
debug: 4.3.4
|
||||||
minimatch: 3.1.2
|
minimatch: 3.1.2
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
@ -5342,48 +5342,48 @@ packages:
|
||||||
os-filter-obj: 2.0.0
|
os-filter-obj: 2.0.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.2:
|
/@msgpackr-extract/msgpackr-extract-darwin-arm64@2.2.0:
|
||||||
resolution: {integrity: sha512-9bfjwDxIDWmmOKusUcqdS4Rw+SETlp9Dy39Xui9BEGEk19dDwH0jhipwFzEff/pFg95NKymc6TOTbRKcWeRqyQ==}
|
resolution: {integrity: sha512-Z9LFPzfoJi4mflGWV+rv7o7ZbMU5oAU9VmzCgL240KnqDW65Y2HFCT3MW06/ITJSnbVLacmcEJA8phywK7JinQ==}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.2:
|
/@msgpackr-extract/msgpackr-extract-darwin-x64@2.2.0:
|
||||||
resolution: {integrity: sha512-lwriRAHm1Yg4iDf23Oxm9n/t5Zpw1lVnxYU3HnJPTi2lJRkKTrps1KVgvL6m7WvmhYVt/FIsssWay+k45QHeuw==}
|
resolution: {integrity: sha512-vq0tT8sjZsy4JdSqmadWVw6f66UXqUCabLmUVHZwUFzMgtgoIIQjT4VVRHKvlof3P/dMCkbMJ5hB1oJ9OWHaaw==}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.2:
|
/@msgpackr-extract/msgpackr-extract-linux-arm64@2.2.0:
|
||||||
resolution: {integrity: sha512-FU20Bo66/f7He9Fp9sP2zaJ1Q8L9uLPZQDub/WlUip78JlPeMbVL8546HbZfcW9LNciEXc8d+tThSJjSC+tmsg==}
|
resolution: {integrity: sha512-hlxxLdRmPyq16QCutUtP8Tm6RDWcyaLsRssaHROatgnkOxdleMTgetf9JsdncL8vLh7FVy/RN9i3XR5dnb9cRA==}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@msgpackr-extract/msgpackr-extract-linux-arm@3.0.2:
|
/@msgpackr-extract/msgpackr-extract-linux-arm@2.2.0:
|
||||||
resolution: {integrity: sha512-MOI9Dlfrpi2Cuc7i5dXdxPbFIgbDBGgKR5F2yWEa6FVEtSWncfVNKW5AKjImAQ6CZlBK9tympdsZJ2xThBiWWA==}
|
resolution: {integrity: sha512-SaJ3Qq4lX9Syd2xEo9u3qPxi/OB+5JO/ngJKK97XDpa1C587H9EWYO6KD8995DAjSinWvdHKRrCOXVUC5fvGOg==}
|
||||||
cpu: [arm]
|
cpu: [arm]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@msgpackr-extract/msgpackr-extract-linux-x64@3.0.2:
|
/@msgpackr-extract/msgpackr-extract-linux-x64@2.2.0:
|
||||||
resolution: {integrity: sha512-gsWNDCklNy7Ajk0vBBf9jEx04RUxuDQfBse918Ww+Qb9HCPoGzS+XJTLe96iN3BVK7grnLiYghP/M4L8VsaHeA==}
|
resolution: {integrity: sha512-94y5PJrSOqUNcFKmOl7z319FelCLAE0rz/jPCWS+UtdMZvpa4jrQd+cJPQCLp2Fes1yAW/YUQj/Di6YVT3c3Iw==}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/@msgpackr-extract/msgpackr-extract-win32-x64@3.0.2:
|
/@msgpackr-extract/msgpackr-extract-win32-x64@2.2.0:
|
||||||
resolution: {integrity: sha512-O+6Gs8UeDbyFpbSh2CPEz/UOrrdWPTBYNblZK5CxxLisYt4kGX3Sc+czffFonyjiGSq3jWLwJS/CCJc7tBr4sQ==}
|
resolution: {integrity: sha512-XrC0JzsqQSvOyM3t04FMLO6z5gCuhPE6k4FXuLK5xf52ZbdvcFe1yBmo7meCew9B8G2f0T9iu9t3kfTYRYROgA==}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
@ -8156,7 +8156,7 @@ packages:
|
||||||
'@typescript-eslint/scope-manager': 5.59.8
|
'@typescript-eslint/scope-manager': 5.59.8
|
||||||
'@typescript-eslint/type-utils': 5.59.8(eslint@8.41.0)(typescript@5.1.3)
|
'@typescript-eslint/type-utils': 5.59.8(eslint@8.41.0)(typescript@5.1.3)
|
||||||
'@typescript-eslint/utils': 5.59.8(eslint@8.41.0)(typescript@5.1.3)
|
'@typescript-eslint/utils': 5.59.8(eslint@8.41.0)(typescript@5.1.3)
|
||||||
debug: 4.3.4(supports-color@8.1.1)
|
debug: 4.3.4
|
||||||
eslint: 8.41.0
|
eslint: 8.41.0
|
||||||
grapheme-splitter: 1.0.4
|
grapheme-splitter: 1.0.4
|
||||||
ignore: 5.2.4
|
ignore: 5.2.4
|
||||||
|
@ -8201,7 +8201,7 @@ packages:
|
||||||
'@typescript-eslint/scope-manager': 5.59.8
|
'@typescript-eslint/scope-manager': 5.59.8
|
||||||
'@typescript-eslint/types': 5.59.8
|
'@typescript-eslint/types': 5.59.8
|
||||||
'@typescript-eslint/typescript-estree': 5.59.8(typescript@5.1.3)
|
'@typescript-eslint/typescript-estree': 5.59.8(typescript@5.1.3)
|
||||||
debug: 4.3.4(supports-color@8.1.1)
|
debug: 4.3.4
|
||||||
eslint: 8.41.0
|
eslint: 8.41.0
|
||||||
typescript: 5.1.3
|
typescript: 5.1.3
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
@ -8256,7 +8256,7 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/typescript-estree': 5.59.8(typescript@5.1.3)
|
'@typescript-eslint/typescript-estree': 5.59.8(typescript@5.1.3)
|
||||||
'@typescript-eslint/utils': 5.59.8(eslint@8.41.0)(typescript@5.1.3)
|
'@typescript-eslint/utils': 5.59.8(eslint@8.41.0)(typescript@5.1.3)
|
||||||
debug: 4.3.4(supports-color@8.1.1)
|
debug: 4.3.4
|
||||||
eslint: 8.41.0
|
eslint: 8.41.0
|
||||||
tsutils: 3.21.0(typescript@5.1.3)
|
tsutils: 3.21.0(typescript@5.1.3)
|
||||||
typescript: 5.1.3
|
typescript: 5.1.3
|
||||||
|
@ -8306,7 +8306,7 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/types': 5.59.8
|
'@typescript-eslint/types': 5.59.8
|
||||||
'@typescript-eslint/visitor-keys': 5.59.8
|
'@typescript-eslint/visitor-keys': 5.59.8
|
||||||
debug: 4.3.4(supports-color@8.1.1)
|
debug: 4.3.4
|
||||||
globby: 11.1.0
|
globby: 11.1.0
|
||||||
is-glob: 4.0.3
|
is-glob: 4.0.3
|
||||||
semver: 7.5.1
|
semver: 7.5.1
|
||||||
|
@ -8827,7 +8827,7 @@ packages:
|
||||||
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
|
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
|
||||||
engines: {node: '>= 6.0.0'}
|
engines: {node: '>= 6.0.0'}
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 4.3.4(supports-color@8.1.1)
|
debug: 4.3.4
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
|
@ -8835,7 +8835,7 @@ packages:
|
||||||
resolution: {integrity: sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==}
|
resolution: {integrity: sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==}
|
||||||
engines: {node: '>= 8.0.0'}
|
engines: {node: '>= 8.0.0'}
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 4.3.4(supports-color@8.1.1)
|
debug: 4.3.4
|
||||||
depd: 1.1.2
|
depd: 1.1.2
|
||||||
humanize-ms: 1.2.1
|
humanize-ms: 1.2.1
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
@ -9315,7 +9315,7 @@ packages:
|
||||||
resolution: {integrity: sha512-bbCQdg7bpEv6kGH41RO/3B2/GMMmJSo2iBK+X8AWN9mujtfUipMDfIjsgHCfpnKqoGEQrrmCDKSa5OQ19+fDmg==}
|
resolution: {integrity: sha512-bbCQdg7bpEv6kGH41RO/3B2/GMMmJSo2iBK+X8AWN9mujtfUipMDfIjsgHCfpnKqoGEQrrmCDKSa5OQ19+fDmg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
archy: 1.0.0
|
archy: 1.0.0
|
||||||
debug: 4.3.4(supports-color@8.1.1)
|
debug: 4.3.4
|
||||||
fastq: 1.15.0
|
fastq: 1.15.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
@ -9338,7 +9338,7 @@ packages:
|
||||||
/axios@0.24.0:
|
/axios@0.24.0:
|
||||||
resolution: {integrity: sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==}
|
resolution: {integrity: sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
follow-redirects: 1.15.2(debug@4.3.4)
|
follow-redirects: 1.15.2
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- debug
|
- debug
|
||||||
dev: false
|
dev: false
|
||||||
|
@ -9849,17 +9849,18 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
node-gyp-build: 4.6.0
|
node-gyp-build: 4.6.0
|
||||||
|
|
||||||
/bullmq@3.15.0:
|
/bull@4.10.4:
|
||||||
resolution: {integrity: sha512-U0LSRjuoyIBpnE62T4maCWMYEt3qdBCa1lnlPxYKQmRF/Y+FQ9W6iW5JvNNN+NA5Jet7k0uX71a93EX1zGnrhw==}
|
resolution: {integrity: sha512-o9m/7HjS/Or3vqRd59evBlWCXd9Lp+ALppKseoSKHaykK46SmRjAilX98PgmOz1yeVaurt8D5UtvEt4bUjM3eA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
dependencies:
|
dependencies:
|
||||||
cron-parser: 4.8.1
|
cron-parser: 4.7.1
|
||||||
glob: 8.1.0
|
debuglog: 1.0.1
|
||||||
|
get-port: 5.1.1
|
||||||
ioredis: 5.3.2
|
ioredis: 5.3.2
|
||||||
lodash: 4.17.21
|
lodash: 4.17.21
|
||||||
msgpackr: 1.9.2
|
msgpackr: 1.8.1
|
||||||
semver: 7.5.1
|
semver: 7.5.1
|
||||||
tslib: 2.5.2
|
uuid: 8.3.2
|
||||||
uuid: 9.0.0
|
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
dev: false
|
||||||
|
@ -10749,11 +10750,11 @@ packages:
|
||||||
readable-stream: 3.6.0
|
readable-stream: 3.6.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/cron-parser@4.8.1:
|
/cron-parser@4.7.1:
|
||||||
resolution: {integrity: sha512-jbokKWGcyU4gl6jAfX97E1gDpY12DJ1cLJZmoDzaAln/shZ+S3KBFBuA2Q6WeUN4gJf/8klnV1EfvhA2lK5IRQ==}
|
resolution: {integrity: sha512-WguFaoQ0hQ61SgsCZLHUcNbAvlK0lypKXu62ARguefYmjzaOXIVRNrAmyXzabTwUn4sQvQLkk6bjH+ipGfw8bA==}
|
||||||
engines: {node: '>=12.0.0'}
|
engines: {node: '>=12.0.0'}
|
||||||
dependencies:
|
dependencies:
|
||||||
luxon: 3.3.0
|
luxon: 3.2.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/cropperjs@2.0.0-beta.2:
|
/cropperjs@2.0.0-beta.2:
|
||||||
|
@ -11006,6 +11007,16 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
ms: 2.0.0
|
ms: 2.0.0
|
||||||
|
|
||||||
|
/debug@3.2.7:
|
||||||
|
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
|
||||||
|
peerDependencies:
|
||||||
|
supports-color: '*'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
supports-color:
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
ms: 2.1.3
|
||||||
|
|
||||||
/debug@3.2.7(supports-color@8.1.1):
|
/debug@3.2.7(supports-color@8.1.1):
|
||||||
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
|
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
@ -11016,6 +11027,18 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
ms: 2.1.3
|
ms: 2.1.3
|
||||||
supports-color: 8.1.1
|
supports-color: 8.1.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/debug@4.3.4:
|
||||||
|
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
|
||||||
|
engines: {node: '>=6.0'}
|
||||||
|
peerDependencies:
|
||||||
|
supports-color: '*'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
supports-color:
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
ms: 2.1.2
|
||||||
|
|
||||||
/debug@4.3.4(supports-color@8.1.1):
|
/debug@4.3.4(supports-color@8.1.1):
|
||||||
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
|
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
|
||||||
|
@ -11029,6 +11052,10 @@ packages:
|
||||||
ms: 2.1.2
|
ms: 2.1.2
|
||||||
supports-color: 8.1.1
|
supports-color: 8.1.1
|
||||||
|
|
||||||
|
/debuglog@1.0.1:
|
||||||
|
resolution: {integrity: sha512-syBZ+rnAK3EgMsH2aYEOLUW7mZSY9Gb+0wUMCFsZvcmiz+HigA0LOcq/HoQqVuGG+EKykunc7QG2bzrponfaSw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/decamelize-keys@1.1.1:
|
/decamelize-keys@1.1.1:
|
||||||
resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==}
|
resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
@ -11722,7 +11749,7 @@ packages:
|
||||||
/eslint-import-resolver-node@0.3.7:
|
/eslint-import-resolver-node@0.3.7:
|
||||||
resolution: {integrity: sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==}
|
resolution: {integrity: sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 3.2.7(supports-color@8.1.1)
|
debug: 3.2.7
|
||||||
is-core-module: 2.11.0
|
is-core-module: 2.11.0
|
||||||
resolve: 1.22.1
|
resolve: 1.22.1
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
@ -11780,7 +11807,7 @@ packages:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/parser': 5.59.8(eslint@8.41.0)(typescript@5.1.3)
|
'@typescript-eslint/parser': 5.59.8(eslint@8.41.0)(typescript@5.1.3)
|
||||||
debug: 3.2.7(supports-color@8.1.1)
|
debug: 3.2.7
|
||||||
eslint: 8.41.0
|
eslint: 8.41.0
|
||||||
eslint-import-resolver-node: 0.3.7
|
eslint-import-resolver-node: 0.3.7
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
@ -11834,7 +11861,7 @@ packages:
|
||||||
array-includes: 3.1.6
|
array-includes: 3.1.6
|
||||||
array.prototype.flat: 1.3.1
|
array.prototype.flat: 1.3.1
|
||||||
array.prototype.flatmap: 1.3.1
|
array.prototype.flatmap: 1.3.1
|
||||||
debug: 3.2.7(supports-color@8.1.1)
|
debug: 3.2.7
|
||||||
doctrine: 2.1.0
|
doctrine: 2.1.0
|
||||||
eslint: 8.41.0
|
eslint: 8.41.0
|
||||||
eslint-import-resolver-node: 0.3.7
|
eslint-import-resolver-node: 0.3.7
|
||||||
|
@ -11960,7 +11987,7 @@ packages:
|
||||||
ajv: 6.12.6
|
ajv: 6.12.6
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
cross-spawn: 7.0.3
|
cross-spawn: 7.0.3
|
||||||
debug: 4.3.4(supports-color@8.1.1)
|
debug: 4.3.4
|
||||||
doctrine: 3.0.0
|
doctrine: 3.0.0
|
||||||
escape-string-regexp: 4.0.0
|
escape-string-regexp: 4.0.0
|
||||||
eslint-scope: 7.2.0
|
eslint-scope: 7.2.0
|
||||||
|
@ -12724,6 +12751,16 @@ packages:
|
||||||
readable-stream: 2.3.7
|
readable-stream: 2.3.7
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/follow-redirects@1.15.2:
|
||||||
|
resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
|
||||||
|
engines: {node: '>=4.0'}
|
||||||
|
peerDependencies:
|
||||||
|
debug: '*'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
debug:
|
||||||
|
optional: true
|
||||||
|
dev: false
|
||||||
|
|
||||||
/follow-redirects@1.15.2(debug@4.3.4):
|
/follow-redirects@1.15.2(debug@4.3.4):
|
||||||
resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
|
resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
|
||||||
engines: {node: '>=4.0'}
|
engines: {node: '>=4.0'}
|
||||||
|
@ -12734,6 +12771,7 @@ packages:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 4.3.4(supports-color@8.1.1)
|
debug: 4.3.4(supports-color@8.1.1)
|
||||||
|
dev: true
|
||||||
|
|
||||||
/for-each@0.3.3:
|
/for-each@0.3.3:
|
||||||
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
|
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
|
||||||
|
@ -13003,7 +13041,6 @@ packages:
|
||||||
/get-port@5.1.1:
|
/get-port@5.1.1:
|
||||||
resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==}
|
resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/get-stream@3.0.0:
|
/get-stream@3.0.0:
|
||||||
resolution: {integrity: sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==}
|
resolution: {integrity: sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==}
|
||||||
|
@ -13610,7 +13647,7 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tootallnate/once': 2.0.0
|
'@tootallnate/once': 2.0.0
|
||||||
agent-base: 6.0.2
|
agent-base: 6.0.2
|
||||||
debug: 4.3.4(supports-color@8.1.1)
|
debug: 4.3.4
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
dev: false
|
||||||
|
@ -13660,7 +13697,7 @@ packages:
|
||||||
engines: {node: '>= 4.5.0'}
|
engines: {node: '>= 4.5.0'}
|
||||||
dependencies:
|
dependencies:
|
||||||
agent-base: 4.3.0
|
agent-base: 4.3.0
|
||||||
debug: 3.2.7(supports-color@8.1.1)
|
debug: 3.2.7
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
dev: false
|
||||||
|
@ -13681,7 +13718,7 @@ packages:
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
dependencies:
|
dependencies:
|
||||||
agent-base: 6.0.2
|
agent-base: 6.0.2
|
||||||
debug: 4.3.4(supports-color@8.1.1)
|
debug: 4.3.4
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
|
@ -13846,7 +13883,7 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@ioredis/commands': 1.2.0
|
'@ioredis/commands': 1.2.0
|
||||||
cluster-key-slot: 1.1.2
|
cluster-key-slot: 1.1.2
|
||||||
debug: 4.3.4(supports-color@8.1.1)
|
debug: 4.3.4
|
||||||
denque: 2.1.0
|
denque: 2.1.0
|
||||||
lodash.defaults: 4.2.0
|
lodash.defaults: 4.2.0
|
||||||
lodash.isarguments: 3.1.0
|
lodash.isarguments: 3.1.0
|
||||||
|
@ -14428,7 +14465,7 @@ packages:
|
||||||
resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==}
|
resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 4.3.4(supports-color@8.1.1)
|
debug: 4.3.4
|
||||||
istanbul-lib-coverage: 3.2.0
|
istanbul-lib-coverage: 3.2.0
|
||||||
source-map: 0.6.1
|
source-map: 0.6.1
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
@ -15711,8 +15748,8 @@ packages:
|
||||||
engines: {node: '>=16.14'}
|
engines: {node: '>=16.14'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/luxon@3.3.0:
|
/luxon@3.2.1:
|
||||||
resolution: {integrity: sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg==}
|
resolution: {integrity: sha512-QrwPArQCNLAKGO/C+ZIilgIuDnEnKx5QYODdDtbFaxzsbZcc/a7WFq7MhsVYgRlwawLtvOUESTlfJ+hc/USqPg==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
@ -16190,26 +16227,25 @@ packages:
|
||||||
engines: {node: '>=12.13'}
|
engines: {node: '>=12.13'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/msgpackr-extract@3.0.2:
|
/msgpackr-extract@2.2.0:
|
||||||
resolution: {integrity: sha512-SdzXp4kD/Qf8agZ9+iTu6eql0m3kWm1A2y1hkpTeVNENutaB0BwHlSvAIaMxwntmRUAUjon2V4L8Z/njd0Ct8A==}
|
resolution: {integrity: sha512-0YcvWSv7ZOGl9Od6Y5iJ3XnPww8O7WLcpYMDwX+PAA/uXLDtyw94PJv9GLQV/nnp3cWlDhMoyKZIQLrx33sWog==}
|
||||||
hasBin: true
|
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
dependencies:
|
dependencies:
|
||||||
node-gyp-build-optional-packages: 5.0.7
|
node-gyp-build-optional-packages: 5.0.3
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@msgpackr-extract/msgpackr-extract-darwin-arm64': 3.0.2
|
'@msgpackr-extract/msgpackr-extract-darwin-arm64': 2.2.0
|
||||||
'@msgpackr-extract/msgpackr-extract-darwin-x64': 3.0.2
|
'@msgpackr-extract/msgpackr-extract-darwin-x64': 2.2.0
|
||||||
'@msgpackr-extract/msgpackr-extract-linux-arm': 3.0.2
|
'@msgpackr-extract/msgpackr-extract-linux-arm': 2.2.0
|
||||||
'@msgpackr-extract/msgpackr-extract-linux-arm64': 3.0.2
|
'@msgpackr-extract/msgpackr-extract-linux-arm64': 2.2.0
|
||||||
'@msgpackr-extract/msgpackr-extract-linux-x64': 3.0.2
|
'@msgpackr-extract/msgpackr-extract-linux-x64': 2.2.0
|
||||||
'@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.2
|
'@msgpackr-extract/msgpackr-extract-win32-x64': 2.2.0
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
/msgpackr@1.9.2:
|
/msgpackr@1.8.1:
|
||||||
resolution: {integrity: sha512-xtDgI3Xv0AAiZWLRGDchyzBwU6aq0rwJ+W+5Y4CZhEWtkl/hJtFFLc+3JtGTw7nz1yquxs7nL8q/yA2aqpflIQ==}
|
resolution: {integrity: sha512-05fT4J8ZqjYlR4QcRDIhLCYKUOHXk7C/xa62GzMKj74l3up9k2QZ3LgFc6qWdsPHl91QA2WLWqWc8b8t7GLNNw==}
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
msgpackr-extract: 3.0.2
|
msgpackr-extract: 2.2.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/msw-storybook-addon@1.8.0(msw@1.2.1):
|
/msw-storybook-addon@1.8.0(msw@1.2.1):
|
||||||
|
@ -16362,7 +16398,7 @@ packages:
|
||||||
resolution: {integrity: sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==}
|
resolution: {integrity: sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==}
|
||||||
engines: {node: '>= 4.4.x'}
|
engines: {node: '>= 4.4.x'}
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 3.2.7(supports-color@8.1.1)
|
debug: 3.2.7
|
||||||
iconv-lite: 0.4.24
|
iconv-lite: 0.4.24
|
||||||
sax: 1.2.4
|
sax: 1.2.4
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
@ -16462,9 +16498,8 @@ packages:
|
||||||
fetch-blob: 3.2.0
|
fetch-blob: 3.2.0
|
||||||
formdata-polyfill: 4.0.10
|
formdata-polyfill: 4.0.10
|
||||||
|
|
||||||
/node-gyp-build-optional-packages@5.0.7:
|
/node-gyp-build-optional-packages@5.0.3:
|
||||||
resolution: {integrity: sha512-YlCCc6Wffkx0kHkmam79GKvDQ6x+QZkMjFGrIMxgFNILFvGSbCp2fCBC55pGTT9gVaz8Na5CLmxt/urtzRv36w==}
|
resolution: {integrity: sha512-k75jcVzk5wnnc/FMxsf4udAoTEUv2jY3ycfdSd3yWu6Cnd1oee6/CfZJApyscA4FJOmdoixWwiwOyf16RzD5JA==}
|
||||||
hasBin: true
|
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
@ -19467,7 +19502,7 @@ packages:
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
dependencies:
|
dependencies:
|
||||||
agent-base: 6.0.2
|
agent-base: 6.0.2
|
||||||
debug: 4.3.4(supports-color@8.1.1)
|
debug: 4.3.4
|
||||||
socks: 2.7.1
|
socks: 2.7.1
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
@ -20586,7 +20621,7 @@ packages:
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
cli-highlight: 2.1.11
|
cli-highlight: 2.1.11
|
||||||
date-fns: 2.30.0
|
date-fns: 2.30.0
|
||||||
debug: 4.3.4(supports-color@8.1.1)
|
debug: 4.3.4
|
||||||
dotenv: 16.0.3
|
dotenv: 16.0.3
|
||||||
glob: 8.1.0
|
glob: 8.1.0
|
||||||
ioredis: 5.3.2
|
ioredis: 5.3.2
|
||||||
|
|
Loading…
Reference in a new issue