From 9d026975bcd35339592c62ae86ace1179a55b4af Mon Sep 17 00:00:00 2001 From: かっこかり <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Sat, 5 Oct 2024 16:20:44 +0900 Subject: fix(backend/test): #14558 以降e2eテストがたまに失敗する問題を修正 (#14709) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(backend/test): MisskeyIO#727 以降e2eテストがたまに失敗する問題を修正 (MisskeyIO#735) * :v: --------- Co-authored-by: まっちゃとーにゅ <17376330+u1-liquid@users.noreply.github.com> --- packages/backend/src/core/NoteCreateService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/backend/src/core/NoteCreateService.ts') diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts index 89e3eafa0e..0ce57f16e6 100644 --- a/packages/backend/src/core/NoteCreateService.ts +++ b/packages/backend/src/core/NoteCreateService.ts @@ -218,7 +218,7 @@ export class NoteCreateService implements OnApplicationShutdown { private utilityService: UtilityService, private userBlockingService: UserBlockingService, ) { - this.updateNotesCountQueue = new CollapsedQueue(60 * 1000 * 5, this.collapseNotesCount, this.performUpdateNotesCount); + this.updateNotesCountQueue = new CollapsedQueue(process.env.NODE_ENV !== 'test' ? 60 * 1000 * 5 : 0, this.collapseNotesCount, this.performUpdateNotesCount); } @bindThis -- cgit v1.2.3-freya From ff47fef5725ba31efc7016534c2d9db8b0ad242a Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Sun, 13 Oct 2024 20:22:16 +0900 Subject: feat: リモートサーバーのサーバー情報を収集しないオプション (#14634) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * wip * wip * Update FetchInstanceMetadataService.ts * Update FetchInstanceMetadataService.ts * Update types.ts --- locales/index.d.ts | 4 ++ locales/ja-JP.yml | 1 + ...27318020265-enableStatsForFederatedInstances.js | 16 ++++++ packages/backend/src/core/AccountMoveService.ts | 16 +++--- .../backend/src/core/FederatedInstanceService.ts | 20 +++++++- .../src/core/FetchInstanceMetadataService.ts | 2 +- packages/backend/src/core/NoteCreateService.ts | 16 +++--- packages/backend/src/core/NoteDeleteService.ts | 16 +++--- packages/backend/src/core/UserFollowingService.ts | 60 ++++++++++++---------- .../src/core/activitypub/models/ApPersonService.ts | 16 +++--- packages/backend/src/models/Meta.ts | 5 ++ .../queue/processors/DeliverProcessorService.ts | 31 +++++++---- .../src/queue/processors/InboxProcessorService.ts | 20 +++++--- .../backend/src/server/api/endpoints/admin/meta.ts | 5 ++ .../src/server/api/endpoints/admin/update-meta.ts | 5 ++ .../test/unit/FetchInstanceMetadataService.ts | 20 ++++---- packages/frontend/src/pages/admin/performance.vue | 16 ++++++ packages/misskey-js/src/autogen/types.ts | 2 + 18 files changed, 185 insertions(+), 86 deletions(-) create mode 100644 packages/backend/migration/1727318020265-enableStatsForFederatedInstances.js (limited to 'packages/backend/src/core/NoteCreateService.ts') diff --git a/locales/index.d.ts b/locales/index.d.ts index 7585410291..3ffb67f31c 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -4366,6 +4366,10 @@ export interface Locale extends ILocale { * リモートサーバーのチャートを生成 */ "enableChartsForFederatedInstances": string; + /** + * リモートサーバーの情報を取得 + */ + "enableStatsForFederatedInstances": string; /** * ノートのアクションにクリップを追加 */ diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 330f7ef473..919be1e3ec 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1087,6 +1087,7 @@ retryAllQueuesConfirmTitle: "今すぐ再試行しますか?" retryAllQueuesConfirmText: "一時的にサーバーの負荷が増大することがあります。" enableChartsForRemoteUser: "リモートユーザーのチャートを生成" enableChartsForFederatedInstances: "リモートサーバーのチャートを生成" +enableStatsForFederatedInstances: "リモートサーバーの情報を取得" showClipButtonInNoteFooter: "ノートのアクションにクリップを追加" reactionsDisplaySize: "リアクションの表示サイズ" limitWidthOfReaction: "リアクションの最大横幅を制限し、縮小して表示する" diff --git a/packages/backend/migration/1727318020265-enableStatsForFederatedInstances.js b/packages/backend/migration/1727318020265-enableStatsForFederatedInstances.js new file mode 100644 index 0000000000..4ff520172b --- /dev/null +++ b/packages/backend/migration/1727318020265-enableStatsForFederatedInstances.js @@ -0,0 +1,16 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export class EnableStatsForFederatedInstances1727318020265 { + name = 'EnableStatsForFederatedInstances1727318020265' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "enableStatsForFederatedInstances" boolean NOT NULL DEFAULT true`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "enableStatsForFederatedInstances"`); + } +} diff --git a/packages/backend/src/core/AccountMoveService.ts b/packages/backend/src/core/AccountMoveService.ts index 6e3125044c..24d11f29ff 100644 --- a/packages/backend/src/core/AccountMoveService.ts +++ b/packages/backend/src/core/AccountMoveService.ts @@ -274,13 +274,15 @@ export class AccountMoveService { } // Update instance stats by decreasing remote followers count by the number of local followers who were following the old account. - if (this.userEntityService.isRemoteUser(oldAccount)) { - this.federatedInstanceService.fetch(oldAccount.host).then(async i => { - this.instancesRepository.decrement({ id: i.id }, 'followersCount', localFollowerIds.length); - if (this.meta.enableChartsForFederatedInstances) { - this.instanceChart.updateFollowers(i.host, false); - } - }); + if (this.meta.enableStatsForFederatedInstances) { + if (this.userEntityService.isRemoteUser(oldAccount)) { + this.federatedInstanceService.fetchOrRegister(oldAccount.host).then(async i => { + this.instancesRepository.decrement({ id: i.id }, 'followersCount', localFollowerIds.length); + if (this.meta.enableChartsForFederatedInstances) { + this.instanceChart.updateFollowers(i.host, false); + } + }); + } } // FIXME: expensive? diff --git a/packages/backend/src/core/FederatedInstanceService.ts b/packages/backend/src/core/FederatedInstanceService.ts index 7aeeb78178..73bbf03b26 100644 --- a/packages/backend/src/core/FederatedInstanceService.ts +++ b/packages/backend/src/core/FederatedInstanceService.ts @@ -47,7 +47,7 @@ export class FederatedInstanceService implements OnApplicationShutdown { } @bindThis - public async fetch(host: string): Promise { + public async fetchOrRegister(host: string): Promise { host = this.utilityService.toPuny(host); const cached = await this.federatedInstanceCache.get(host); @@ -70,6 +70,24 @@ export class FederatedInstanceService implements OnApplicationShutdown { } } + @bindThis + public async fetch(host: string): Promise { + host = this.utilityService.toPuny(host); + + const cached = await this.federatedInstanceCache.get(host); + if (cached !== undefined) return cached; + + const index = await this.instancesRepository.findOneBy({ host }); + + if (index == null) { + this.federatedInstanceCache.set(host, null); + return null; + } else { + this.federatedInstanceCache.set(host, index); + return index; + } + } + @bindThis public async update(id: MiInstance['id'], data: Partial): Promise { const result = await this.instancesRepository.createQueryBuilder().update() diff --git a/packages/backend/src/core/FetchInstanceMetadataService.ts b/packages/backend/src/core/FetchInstanceMetadataService.ts index aa16468ecb..987999bce7 100644 --- a/packages/backend/src/core/FetchInstanceMetadataService.ts +++ b/packages/backend/src/core/FetchInstanceMetadataService.ts @@ -82,7 +82,7 @@ export class FetchInstanceMetadataService { try { if (!force) { - const _instance = await this.federatedInstanceService.fetch(host); + const _instance = await this.federatedInstanceService.fetchOrRegister(host); const now = Date.now(); if (_instance && _instance.infoUpdatedAt && (now - _instance.infoUpdatedAt.getTime() < 1000 * 60 * 60 * 24)) { // unlock at the finally caluse diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts index 0ce57f16e6..3647fa7231 100644 --- a/packages/backend/src/core/NoteCreateService.ts +++ b/packages/backend/src/core/NoteCreateService.ts @@ -511,13 +511,15 @@ export class NoteCreateService implements OnApplicationShutdown { } // Register host - if (this.userEntityService.isRemoteUser(user)) { - this.federatedInstanceService.fetch(user.host).then(async i => { - this.updateNotesCountQueue.enqueue(i.id, 1); - if (this.meta.enableChartsForFederatedInstances) { - this.instanceChart.updateNote(i.host, note, true); - } - }); + if (this.meta.enableStatsForFederatedInstances) { + if (this.userEntityService.isRemoteUser(user)) { + this.federatedInstanceService.fetchOrRegister(user.host).then(async i => { + this.updateNotesCountQueue.enqueue(i.id, 1); + if (this.meta.enableChartsForFederatedInstances) { + this.instanceChart.updateNote(i.host, note, true); + } + }); + } } // ハッシュタグ更新 diff --git a/packages/backend/src/core/NoteDeleteService.ts b/packages/backend/src/core/NoteDeleteService.ts index f9f8ace386..4ecd2592b2 100644 --- a/packages/backend/src/core/NoteDeleteService.ts +++ b/packages/backend/src/core/NoteDeleteService.ts @@ -106,13 +106,15 @@ export class NoteDeleteService { this.perUserNotesChart.update(user, note, false); } - if (this.userEntityService.isRemoteUser(user)) { - this.federatedInstanceService.fetch(user.host).then(async i => { - this.instancesRepository.decrement({ id: i.id }, 'notesCount', 1); - if (this.meta.enableChartsForFederatedInstances) { - this.instanceChart.updateNote(i.host, note, false); - } - }); + if (this.meta.enableStatsForFederatedInstances) { + if (this.userEntityService.isRemoteUser(user)) { + this.federatedInstanceService.fetchOrRegister(user.host).then(async i => { + this.instancesRepository.decrement({ id: i.id }, 'notesCount', 1); + if (this.meta.enableChartsForFederatedInstances) { + this.instanceChart.updateNote(i.host, note, false); + } + }); + } } } diff --git a/packages/backend/src/core/UserFollowingService.ts b/packages/backend/src/core/UserFollowingService.ts index 77e7b60bea..8963003057 100644 --- a/packages/backend/src/core/UserFollowingService.ts +++ b/packages/backend/src/core/UserFollowingService.ts @@ -305,20 +305,22 @@ export class UserFollowingService implements OnModuleInit { //#endregion //#region Update instance stats - if (this.userEntityService.isRemoteUser(follower) && this.userEntityService.isLocalUser(followee)) { - this.federatedInstanceService.fetch(follower.host).then(async i => { - this.instancesRepository.increment({ id: i.id }, 'followingCount', 1); - if (this.meta.enableChartsForFederatedInstances) { - this.instanceChart.updateFollowing(i.host, true); - } - }); - } else if (this.userEntityService.isLocalUser(follower) && this.userEntityService.isRemoteUser(followee)) { - this.federatedInstanceService.fetch(followee.host).then(async i => { - this.instancesRepository.increment({ id: i.id }, 'followersCount', 1); - if (this.meta.enableChartsForFederatedInstances) { - this.instanceChart.updateFollowers(i.host, true); - } - }); + if (this.meta.enableStatsForFederatedInstances) { + if (this.userEntityService.isRemoteUser(follower) && this.userEntityService.isLocalUser(followee)) { + this.federatedInstanceService.fetchOrRegister(follower.host).then(async i => { + this.instancesRepository.increment({ id: i.id }, 'followingCount', 1); + if (this.meta.enableChartsForFederatedInstances) { + this.instanceChart.updateFollowing(i.host, true); + } + }); + } else if (this.userEntityService.isLocalUser(follower) && this.userEntityService.isRemoteUser(followee)) { + this.federatedInstanceService.fetchOrRegister(followee.host).then(async i => { + this.instancesRepository.increment({ id: i.id }, 'followersCount', 1); + if (this.meta.enableChartsForFederatedInstances) { + this.instanceChart.updateFollowers(i.host, true); + } + }); + } } //#endregion @@ -437,20 +439,22 @@ export class UserFollowingService implements OnModuleInit { //#endregion //#region Update instance stats - if (this.userEntityService.isRemoteUser(follower) && this.userEntityService.isLocalUser(followee)) { - this.federatedInstanceService.fetch(follower.host).then(async i => { - this.instancesRepository.decrement({ id: i.id }, 'followingCount', 1); - if (this.meta.enableChartsForFederatedInstances) { - this.instanceChart.updateFollowing(i.host, false); - } - }); - } else if (this.userEntityService.isLocalUser(follower) && this.userEntityService.isRemoteUser(followee)) { - this.federatedInstanceService.fetch(followee.host).then(async i => { - this.instancesRepository.decrement({ id: i.id }, 'followersCount', 1); - if (this.meta.enableChartsForFederatedInstances) { - this.instanceChart.updateFollowers(i.host, false); - } - }); + if (this.meta.enableStatsForFederatedInstances) { + if (this.userEntityService.isRemoteUser(follower) && this.userEntityService.isLocalUser(followee)) { + this.federatedInstanceService.fetchOrRegister(follower.host).then(async i => { + this.instancesRepository.decrement({ id: i.id }, 'followingCount', 1); + if (this.meta.enableChartsForFederatedInstances) { + this.instanceChart.updateFollowing(i.host, false); + } + }); + } else if (this.userEntityService.isLocalUser(follower) && this.userEntityService.isRemoteUser(followee)) { + this.federatedInstanceService.fetchOrRegister(followee.host).then(async i => { + this.instancesRepository.decrement({ id: i.id }, 'followersCount', 1); + if (this.meta.enableChartsForFederatedInstances) { + this.instanceChart.updateFollowers(i.host, false); + } + }); + } } //#endregion diff --git a/packages/backend/src/core/activitypub/models/ApPersonService.ts b/packages/backend/src/core/activitypub/models/ApPersonService.ts index e042a85782..73281078e5 100644 --- a/packages/backend/src/core/activitypub/models/ApPersonService.ts +++ b/packages/backend/src/core/activitypub/models/ApPersonService.ts @@ -408,13 +408,15 @@ export class ApPersonService implements OnModuleInit { this.cacheService.uriPersonCache.set(user.uri, user); // Register host - this.federatedInstanceService.fetch(host).then(i => { - this.instancesRepository.increment({ id: i.id }, 'usersCount', 1); - this.fetchInstanceMetadataService.fetchInstanceMetadata(i); - if (this.meta.enableChartsForFederatedInstances) { - this.instanceChart.newUser(i.host); - } - }); + if (this.meta.enableStatsForFederatedInstances) { + this.federatedInstanceService.fetchOrRegister(host).then(i => { + this.instancesRepository.increment({ id: i.id }, 'usersCount', 1); + if (this.meta.enableChartsForFederatedInstances) { + this.instanceChart.newUser(i.host); + } + this.fetchInstanceMetadataService.fetchInstanceMetadata(i); + }); + } this.usersChart.update(user, true); diff --git a/packages/backend/src/models/Meta.ts b/packages/backend/src/models/Meta.ts index 5ceee1c3f5..ad5e31ad6f 100644 --- a/packages/backend/src/models/Meta.ts +++ b/packages/backend/src/models/Meta.ts @@ -529,6 +529,11 @@ export class MiMeta { }) public enableChartsForFederatedInstances: boolean; + @Column('boolean', { + default: true, + }) + public enableStatsForFederatedInstances: boolean; + @Column('boolean', { default: false, }) diff --git a/packages/backend/src/queue/processors/DeliverProcessorService.ts b/packages/backend/src/queue/processors/DeliverProcessorService.ts index 9590a4fe71..5a16496011 100644 --- a/packages/backend/src/queue/processors/DeliverProcessorService.ts +++ b/packages/backend/src/queue/processors/DeliverProcessorService.ts @@ -74,8 +74,17 @@ export class DeliverProcessorService { try { await this.apRequestService.signedPost(job.data.user, job.data.to, job.data.content, job.data.digest); - // Update stats - this.federatedInstanceService.fetch(host).then(i => { + this.apRequestChart.deliverSucc(); + this.federationChart.deliverd(host, true); + + // Update instance stats + process.nextTick(async () => { + const i = await (this.meta.enableStatsForFederatedInstances + ? this.federatedInstanceService.fetchOrRegister(host) + : this.federatedInstanceService.fetch(host)); + + if (i == null) return; + if (i.isNotResponding) { this.federatedInstanceService.update(i.id, { isNotResponding: false, @@ -83,9 +92,9 @@ export class DeliverProcessorService { }); } - this.fetchInstanceMetadataService.fetchInstanceMetadata(i); - this.apRequestChart.deliverSucc(); - this.federationChart.deliverd(i.host, true); + if (this.meta.enableStatsForFederatedInstances) { + this.fetchInstanceMetadataService.fetchInstanceMetadata(i); + } if (this.meta.enableChartsForFederatedInstances) { this.instanceChart.requestSent(i.host, true); @@ -94,8 +103,11 @@ export class DeliverProcessorService { return 'Success'; } catch (res) { - // Update stats - this.federatedInstanceService.fetch(host).then(i => { + this.apRequestChart.deliverFail(); + this.federationChart.deliverd(host, false); + + // Update instance stats + this.federatedInstanceService.fetchOrRegister(host).then(i => { if (!i.isNotResponding) { this.federatedInstanceService.update(i.id, { isNotResponding: true, @@ -116,9 +128,6 @@ export class DeliverProcessorService { }); } - this.apRequestChart.deliverFail(); - this.federationChart.deliverd(i.host, false); - if (this.meta.enableChartsForFederatedInstances) { this.instanceChart.requestSent(i.host, false); } @@ -129,7 +138,7 @@ export class DeliverProcessorService { if (!res.isRetryable) { // 相手が閉鎖していることを明示しているため、配送停止する if (job.data.isSharedInbox && res.statusCode === 410) { - this.federatedInstanceService.fetch(host).then(i => { + this.federatedInstanceService.fetchOrRegister(host).then(i => { this.federatedInstanceService.update(i.id, { suspensionState: 'goneSuspended', }); diff --git a/packages/backend/src/queue/processors/InboxProcessorService.ts b/packages/backend/src/queue/processors/InboxProcessorService.ts index a77c968395..95d764e4d8 100644 --- a/packages/backend/src/queue/processors/InboxProcessorService.ts +++ b/packages/backend/src/queue/processors/InboxProcessorService.ts @@ -192,21 +192,27 @@ export class InboxProcessorService implements OnApplicationShutdown { } } - // Update stats - this.federatedInstanceService.fetch(authUser.user.host).then(i => { + this.apRequestChart.inbox(); + this.federationChart.inbox(authUser.user.host); + + // Update instance stats + process.nextTick(async () => { + const i = await (this.meta.enableStatsForFederatedInstances + ? this.federatedInstanceService.fetchOrRegister(authUser.user.host) + : this.federatedInstanceService.fetch(authUser.user.host)); + + if (i == null) return; + this.updateInstanceQueue.enqueue(i.id, { latestRequestReceivedAt: new Date(), shouldUnsuspend: i.suspensionState === 'autoSuspendedForNotResponding', }); - this.fetchInstanceMetadataService.fetchInstanceMetadata(i); - - this.apRequestChart.inbox(); - this.federationChart.inbox(i.host); - if (this.meta.enableChartsForFederatedInstances) { this.instanceChart.requestReceived(i.host); } + + this.fetchInstanceMetadataService.fetchInstanceMetadata(i); }); // アクティビティを処理 diff --git a/packages/backend/src/server/api/endpoints/admin/meta.ts b/packages/backend/src/server/api/endpoints/admin/meta.ts index 16cbbc9aa4..64e3cc33bd 100644 --- a/packages/backend/src/server/api/endpoints/admin/meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/meta.ts @@ -348,6 +348,10 @@ export const meta = { type: 'boolean', optional: false, nullable: false, }, + enableStatsForFederatedInstances: { + type: 'boolean', + optional: false, nullable: false, + }, enableServerMachineStats: { type: 'boolean', optional: false, nullable: false, @@ -635,6 +639,7 @@ export default class extends Endpoint { // eslint- truemailAuthKey: instance.truemailAuthKey, enableChartsForRemoteUser: instance.enableChartsForRemoteUser, enableChartsForFederatedInstances: instance.enableChartsForFederatedInstances, + enableStatsForFederatedInstances: instance.enableStatsForFederatedInstances, enableServerMachineStats: instance.enableServerMachineStats, enableIdenticonGeneration: instance.enableIdenticonGeneration, bannedEmailDomains: instance.bannedEmailDomains, diff --git a/packages/backend/src/server/api/endpoints/admin/update-meta.ts b/packages/backend/src/server/api/endpoints/admin/update-meta.ts index 536645e0d7..38ef0d1de8 100644 --- a/packages/backend/src/server/api/endpoints/admin/update-meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/update-meta.ts @@ -136,6 +136,7 @@ export const paramDef = { truemailAuthKey: { type: 'string', nullable: true }, enableChartsForRemoteUser: { type: 'boolean' }, enableChartsForFederatedInstances: { type: 'boolean' }, + enableStatsForFederatedInstances: { type: 'boolean' }, enableServerMachineStats: { type: 'boolean' }, enableIdenticonGeneration: { type: 'boolean' }, serverRules: { type: 'array', items: { type: 'string' } }, @@ -578,6 +579,10 @@ export default class extends Endpoint { // eslint- set.enableChartsForFederatedInstances = ps.enableChartsForFederatedInstances; } + if (ps.enableStatsForFederatedInstances !== undefined) { + set.enableStatsForFederatedInstances = ps.enableStatsForFederatedInstances; + } + if (ps.enableServerMachineStats !== undefined) { set.enableServerMachineStats = ps.enableServerMachineStats; } diff --git a/packages/backend/test/unit/FetchInstanceMetadataService.ts b/packages/backend/test/unit/FetchInstanceMetadataService.ts index bf8f3ab0e3..1e3605aafc 100644 --- a/packages/backend/test/unit/FetchInstanceMetadataService.ts +++ b/packages/backend/test/unit/FetchInstanceMetadataService.ts @@ -8,6 +8,7 @@ process.env.NODE_ENV = 'test'; import { jest } from '@jest/globals'; import { Test } from '@nestjs/testing'; import { Redis } from 'ioredis'; +import type { TestingModule } from '@nestjs/testing'; import { GlobalModule } from '@/GlobalModule.js'; import { FetchInstanceMetadataService } from '@/core/FetchInstanceMetadataService.js'; import { FederatedInstanceService } from '@/core/FederatedInstanceService.js'; @@ -16,7 +17,6 @@ import { LoggerService } from '@/core/LoggerService.js'; import { UtilityService } from '@/core/UtilityService.js'; import { IdService } from '@/core/IdService.js'; import { DI } from '@/di-symbols.js'; -import type { TestingModule } from '@nestjs/testing'; function mockRedis() { const hash = {} as any; @@ -52,7 +52,7 @@ describe('FetchInstanceMetadataService', () => { if (token === HttpRequestService) { return { getJson: jest.fn(), getHtml: jest.fn(), send: jest.fn() }; } else if (token === FederatedInstanceService) { - return { fetch: jest.fn() }; + return { fetchOrRegister: jest.fn() }; } else if (token === DI.redis) { return mockRedis; } @@ -75,7 +75,7 @@ describe('FetchInstanceMetadataService', () => { test('Lock and update', async () => { redisClient.set = mockRedis(); const now = Date.now(); - federatedInstanceService.fetch.mockResolvedValue({ infoUpdatedAt: { getTime: () => { return now - 10 * 1000 * 60 * 60 * 24; } } } as any); + federatedInstanceService.fetchOrRegister.mockResolvedValue({ infoUpdatedAt: { getTime: () => { return now - 10 * 1000 * 60 * 60 * 24; } } } as any); httpRequestService.getJson.mockImplementation(() => { throw Error(); }); const tryLockSpy = jest.spyOn(fetchInstanceMetadataService, 'tryLock'); const unlockSpy = jest.spyOn(fetchInstanceMetadataService, 'unlock'); @@ -83,14 +83,14 @@ describe('FetchInstanceMetadataService', () => { await fetchInstanceMetadataService.fetchInstanceMetadata({ host: 'example.com' } as any); expect(tryLockSpy).toHaveBeenCalledTimes(1); expect(unlockSpy).toHaveBeenCalledTimes(1); - expect(federatedInstanceService.fetch).toHaveBeenCalledTimes(1); + expect(federatedInstanceService.fetchOrRegister).toHaveBeenCalledTimes(1); expect(httpRequestService.getJson).toHaveBeenCalled(); }); test('Lock and don\'t update', async () => { redisClient.set = mockRedis(); const now = Date.now(); - federatedInstanceService.fetch.mockResolvedValue({ infoUpdatedAt: { getTime: () => now } } as any); + federatedInstanceService.fetchOrRegister.mockResolvedValue({ infoUpdatedAt: { getTime: () => now } } as any); httpRequestService.getJson.mockImplementation(() => { throw Error(); }); const tryLockSpy = jest.spyOn(fetchInstanceMetadataService, 'tryLock'); const unlockSpy = jest.spyOn(fetchInstanceMetadataService, 'unlock'); @@ -98,14 +98,14 @@ describe('FetchInstanceMetadataService', () => { await fetchInstanceMetadataService.fetchInstanceMetadata({ host: 'example.com' } as any); expect(tryLockSpy).toHaveBeenCalledTimes(1); expect(unlockSpy).toHaveBeenCalledTimes(1); - expect(federatedInstanceService.fetch).toHaveBeenCalledTimes(1); + expect(federatedInstanceService.fetchOrRegister).toHaveBeenCalledTimes(1); expect(httpRequestService.getJson).toHaveBeenCalledTimes(0); }); test('Do nothing when lock not acquired', async () => { redisClient.set = mockRedis(); const now = Date.now(); - federatedInstanceService.fetch.mockResolvedValue({ infoUpdatedAt: { getTime: () => now - 10 * 1000 * 60 * 60 * 24 } } as any); + federatedInstanceService.fetchOrRegister.mockResolvedValue({ infoUpdatedAt: { getTime: () => now - 10 * 1000 * 60 * 60 * 24 } } as any); httpRequestService.getJson.mockImplementation(() => { throw Error(); }); await fetchInstanceMetadataService.tryLock('example.com'); const tryLockSpy = jest.spyOn(fetchInstanceMetadataService, 'tryLock'); @@ -114,14 +114,14 @@ describe('FetchInstanceMetadataService', () => { await fetchInstanceMetadataService.fetchInstanceMetadata({ host: 'example.com' } as any); expect(tryLockSpy).toHaveBeenCalledTimes(1); expect(unlockSpy).toHaveBeenCalledTimes(0); - expect(federatedInstanceService.fetch).toHaveBeenCalledTimes(0); + expect(federatedInstanceService.fetchOrRegister).toHaveBeenCalledTimes(0); expect(httpRequestService.getJson).toHaveBeenCalledTimes(0); }); test('Do when lock not acquired but forced', async () => { redisClient.set = mockRedis(); const now = Date.now(); - federatedInstanceService.fetch.mockResolvedValue({ infoUpdatedAt: { getTime: () => now - 10 * 1000 * 60 * 60 * 24 } } as any); + federatedInstanceService.fetchOrRegister.mockResolvedValue({ infoUpdatedAt: { getTime: () => now - 10 * 1000 * 60 * 60 * 24 } } as any); httpRequestService.getJson.mockImplementation(() => { throw Error(); }); await fetchInstanceMetadataService.tryLock('example.com'); const tryLockSpy = jest.spyOn(fetchInstanceMetadataService, 'tryLock'); @@ -130,7 +130,7 @@ describe('FetchInstanceMetadataService', () => { await fetchInstanceMetadataService.fetchInstanceMetadata({ host: 'example.com' } as any, true); expect(tryLockSpy).toHaveBeenCalledTimes(0); expect(unlockSpy).toHaveBeenCalledTimes(1); - expect(federatedInstanceService.fetch).toHaveBeenCalledTimes(0); + expect(federatedInstanceService.fetchOrRegister).toHaveBeenCalledTimes(0); expect(httpRequestService.getJson).toHaveBeenCalled(); }); }); diff --git a/packages/frontend/src/pages/admin/performance.vue b/packages/frontend/src/pages/admin/performance.vue index 7e0a932f82..12338f0bf9 100644 --- a/packages/frontend/src/pages/admin/performance.vue +++ b/packages/frontend/src/pages/admin/performance.vue @@ -29,6 +29,13 @@ SPDX-License-Identifier: AGPL-3.0-only +
+ + + + +
+
@@ -120,6 +127,7 @@ const meta = await misskeyApi('admin/meta'); const enableServerMachineStats = ref(meta.enableServerMachineStats); const enableIdenticonGeneration = ref(meta.enableIdenticonGeneration); const enableChartsForRemoteUser = ref(meta.enableChartsForRemoteUser); +const enableStatsForFederatedInstances = ref(meta.enableStatsForFederatedInstances); const enableChartsForFederatedInstances = ref(meta.enableChartsForFederatedInstances); function onChange_enableServerMachineStats(value: boolean) { @@ -146,6 +154,14 @@ function onChange_enableChartsForRemoteUser(value: boolean) { }); } +function onChange_enableStatsForFederatedInstances(value: boolean) { + os.apiWithDialog('admin/update-meta', { + enableStatsForFederatedInstances: value, + }).then(() => { + fetchInstance(true); + }); +} + function onChange_enableChartsForFederatedInstances(value: boolean) { os.apiWithDialog('admin/update-meta', { enableChartsForFederatedInstances: value, diff --git a/packages/misskey-js/src/autogen/types.ts b/packages/misskey-js/src/autogen/types.ts index f61d72e280..6494614026 100644 --- a/packages/misskey-js/src/autogen/types.ts +++ b/packages/misskey-js/src/autogen/types.ts @@ -5165,6 +5165,7 @@ export type operations = { truemailAuthKey: string | null; enableChartsForRemoteUser: boolean; enableChartsForFederatedInstances: boolean; + enableStatsForFederatedInstances: boolean; enableServerMachineStats: boolean; enableIdenticonGeneration: boolean; manifestJsonOverride: string; @@ -9547,6 +9548,7 @@ export type operations = { truemailAuthKey?: string | null; enableChartsForRemoteUser?: boolean; enableChartsForFederatedInstances?: boolean; + enableStatsForFederatedInstances?: boolean; enableServerMachineStats?: boolean; enableIdenticonGeneration?: boolean; serverRules?: string[]; -- cgit v1.2.3-freya From 41ac75a113e3be0313ed0c6b8563e66838c02d42 Mon Sep 17 00:00:00 2001 From: dakkar Date: Fri, 8 Nov 2024 16:45:51 +0000 Subject: fix uses of renamed method `FederatedInstanceService.fetch` will now just load from the DB, it won't do anything if the instance is not already there --- packages/backend/src/core/NoteCreateService.ts | 2 +- packages/backend/src/core/NoteEditService.ts | 4 ++-- packages/backend/src/core/activitypub/ApInboxService.ts | 2 +- packages/backend/src/core/activitypub/models/ApImageService.ts | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'packages/backend/src/core/NoteCreateService.ts') diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts index 3f282655f1..e5808eccdc 100644 --- a/packages/backend/src/core/NoteCreateService.ts +++ b/packages/backend/src/core/NoteCreateService.ts @@ -411,7 +411,7 @@ export class NoteCreateService implements OnApplicationShutdown { } if (user.host && !data.cw) { - await this.federatedInstanceService.fetch(user.host).then(async i => { + await this.federatedInstanceService.fetchOrRegister(user.host).then(async i => { if (i.isNSFW) { data.cw = 'Instance is marked as NSFW'; } diff --git a/packages/backend/src/core/NoteEditService.ts b/packages/backend/src/core/NoteEditService.ts index b52ef8c71e..91b310a065 100644 --- a/packages/backend/src/core/NoteEditService.ts +++ b/packages/backend/src/core/NoteEditService.ts @@ -441,7 +441,7 @@ export class NoteEditService implements OnApplicationShutdown { } if (user.host && !data.cw) { - await this.federatedInstanceService.fetch(user.host).then(async i => { + await this.federatedInstanceService.fetchOrRegister(user.host).then(async i => { if (i.isNSFW) { data.cw = 'Instance is marked as NSFW'; } @@ -593,7 +593,7 @@ export class NoteEditService implements OnApplicationShutdown { // Register host if (this.meta.enableStatsForFederatedInstances) { if (this.userEntityService.isRemoteUser(user)) { - this.federatedInstanceService.fetch(user.host).then(async i => { + this.federatedInstanceService.fetchOrRegister(user.host).then(async i => { if (note.renote && note.text || !note.renote) { this.updateNotesCountQueue.enqueue(i.id, 1); } diff --git a/packages/backend/src/core/activitypub/ApInboxService.ts b/packages/backend/src/core/activitypub/ApInboxService.ts index d54c9544c3..1a2359ac3a 100644 --- a/packages/backend/src/core/activitypub/ApInboxService.ts +++ b/packages/backend/src/core/activitypub/ApInboxService.ts @@ -538,7 +538,7 @@ export class ApInboxService { @bindThis private async flag(actor: MiRemoteUser, activity: IFlag): Promise { // Make sure the source instance is allowed to send reports. - const instance = await this.federatedInstanceService.fetch(actor.host); + const instance = await this.federatedInstanceService.fetchOrRegister(actor.host); if (instance.rejectReports) { throw new Bull.UnrecoverableError(`Rejecting report from instance: ${actor.host}`); } diff --git a/packages/backend/src/core/activitypub/models/ApImageService.ts b/packages/backend/src/core/activitypub/models/ApImageService.ts index 259889d945..4ea22ec64d 100644 --- a/packages/backend/src/core/activitypub/models/ApImageService.ts +++ b/packages/backend/src/core/activitypub/models/ApImageService.ts @@ -73,7 +73,7 @@ export class ApImageService { // 2. or the image is not sensitive const shouldBeCached = this.meta.cacheRemoteFiles && (this.meta.cacheRemoteSensitiveFiles || !image.sensitive); - await this.federatedInstanceService.fetch(actor.host).then(async i => { + await this.federatedInstanceService.fetchOrRegister(actor.host).then(async i => { if (i.isNSFW) { image.sensitive = true; } -- cgit v1.2.3-freya From aa48a0e207fbf37150363052b19a8b41ffcf1630 Mon Sep 17 00:00:00 2001 From: Sayamame-beans <61457993+Sayamame-beans@users.noreply.github.com> Date: Thu, 21 Nov 2024 08:00:50 +0900 Subject: Fix: リノートミュートが新規投稿通知に対して作用していなかった問題を修正 (#15006) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(backend): renoteMute doesn't work for note notification * docs(changelog): update changelog --- CHANGELOG.md | 1 + packages/backend/src/core/NoteCreateService.ts | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) (limited to 'packages/backend/src/core/NoteCreateService.ts') diff --git a/CHANGELOG.md b/CHANGELOG.md index 58b9c4d0cd..0718150fc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,6 +66,7 @@ (Cherry-picked from https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/709) - Fix: User Webhookテスト機能のMock Payloadを修正 - Fix: アカウント削除のモデレーションログが動作していないのを修正 (#14996) +- Fix: リノートミュートが新規投稿通知に対して作用していなかった問題を修正 ### Misskey.js - Fix: Stream初期化時、別途WebSocketを指定する場合の型定義を修正 diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts index 3647fa7231..56ddcefd7c 100644 --- a/packages/backend/src/core/NoteCreateService.ts +++ b/packages/backend/src/core/NoteCreateService.ts @@ -56,6 +56,7 @@ import { isReply } from '@/misc/is-reply.js'; import { trackPromise } from '@/misc/promise-tracker.js'; import { IdentifiableError } from '@/misc/identifiable-error.js'; import { CollapsedQueue } from '@/misc/collapsed-queue.js'; +import { CacheService } from '@/core/CacheService.js'; type NotificationType = 'reply' | 'renote' | 'quote' | 'mention'; @@ -217,6 +218,7 @@ export class NoteCreateService implements OnApplicationShutdown { private instanceChart: InstanceChart, private utilityService: UtilityService, private userBlockingService: UserBlockingService, + private cacheService: CacheService, ) { this.updateNotesCountQueue = new CollapsedQueue(process.env.NODE_ENV !== 'test' ? 60 * 1000 * 5 : 0, this.collapseNotesCount, this.performUpdateNotesCount); } @@ -543,13 +545,21 @@ export class NoteCreateService implements OnApplicationShutdown { this.followingsRepository.findBy({ followeeId: user.id, notify: 'normal', - }).then(followings => { + }).then(async followings => { if (note.visibility !== 'specified') { + const isPureRenote = this.isRenote(data) && !this.isQuote(data) ? true : false; for (const following of followings) { // TODO: ワードミュート考慮 - this.notificationService.createNotification(following.followerId, 'note', { - noteId: note.id, - }, user.id); + let isRenoteMuted = false; + if (isPureRenote) { + const userIdsWhoMeMutingRenotes = await this.cacheService.renoteMutingsCache.fetch(following.followerId); + isRenoteMuted = userIdsWhoMeMutingRenotes.has(user.id); + } + if (!isRenoteMuted) { + this.notificationService.createNotification(following.followerId, 'note', { + noteId: note.id, + }, user.id); + } } } }); -- cgit v1.2.3-freya From efeb5ba08b75660489ab3a01c866b6242358a19b Mon Sep 17 00:00:00 2001 From: dakkar Date: Fri, 22 Nov 2024 12:48:08 +0000 Subject: remove duplicate import --- packages/backend/src/core/NoteCreateService.ts | 1 - packages/backend/src/core/activitypub/ApRequestService.ts | 1 - 2 files changed, 2 deletions(-) (limited to 'packages/backend/src/core/NoteCreateService.ts') diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts index ae98c2fc79..53c6329c04 100644 --- a/packages/backend/src/core/NoteCreateService.ts +++ b/packages/backend/src/core/NoteCreateService.ts @@ -51,7 +51,6 @@ import { FeaturedService } from '@/core/FeaturedService.js'; import { FanoutTimelineService } from '@/core/FanoutTimelineService.js'; import { UtilityService } from '@/core/UtilityService.js'; import { UserBlockingService } from '@/core/UserBlockingService.js'; -import { CacheService } from '@/core/CacheService.js'; import { isReply } from '@/misc/is-reply.js'; import { trackPromise } from '@/misc/promise-tracker.js'; import { isUserRelated } from '@/misc/is-user-related.js'; diff --git a/packages/backend/src/core/activitypub/ApRequestService.ts b/packages/backend/src/core/activitypub/ApRequestService.ts index ca4aabbf49..a5f96dfac1 100644 --- a/packages/backend/src/core/activitypub/ApRequestService.ts +++ b/packages/backend/src/core/activitypub/ApRequestService.ts @@ -19,7 +19,6 @@ import type Logger from '@/logger.js'; import type { IObject } from './type.js'; import { validateContentTypeSetAsActivityPub } from '@/core/activitypub/misc/validator.js'; import { assertActivityMatchesUrls } from '@/core/activitypub/misc/check-against-url.js'; -import { UtilityService } from "@/core/UtilityService.js"; import type { IObject } from './type.js'; type Request = { -- cgit v1.2.3-freya