From f01e6ef6bf061b6c49cc7d9188160e41edad421b Mon Sep 17 00:00:00 2001 From: syuilo Date: Fri, 24 Mar 2023 15:43:36 +0900 Subject: enhance(backend): リモートユーザーのチャート生成を無効にするオプションを追加 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/core/NoteCreateService.ts | 7 +++++-- 1 file changed, 5 insertions(+), 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 2fc2a3d54f..10d74e4218 100644 --- a/packages/backend/src/core/NoteCreateService.ts +++ b/packages/backend/src/core/NoteCreateService.ts @@ -435,9 +435,12 @@ export class NoteCreateService implements OnApplicationShutdown { createdAt: User['createdAt']; isBot: User['isBot']; }, data: Option, silent: boolean, tags: string[], mentionedUsers: MinimumUser[]) { - // 統計を更新 + const meta = await this.metaService.fetch(); + this.notesChart.update(note, true); - this.perUserNotesChart.update(user, note, true); + if (meta.enableChartsForRemoteUser || (user.host == null)) { + this.perUserNotesChart.update(user, note, true); + } // Register host if (this.userEntityService.isRemoteUser(user)) { -- cgit v1.2.3-freya From e4380911135b1aff7c85770d6dabb3e72e9874e7 Mon Sep 17 00:00:00 2001 From: syuilo Date: Fri, 24 Mar 2023 16:43:42 +0900 Subject: refactor(backend): rename cache class --- packages/backend/src/core/CustomEmojiService.ts | 6 +- .../backend/src/core/FederatedInstanceService.ts | 6 +- packages/backend/src/core/InstanceActorService.ts | 6 +- packages/backend/src/core/NoteCreateService.ts | 4 +- packages/backend/src/core/RelayService.ts | 6 +- packages/backend/src/core/RoleService.ts | 10 +-- packages/backend/src/core/UserBlockingService.ts | 6 +- packages/backend/src/core/UserCacheService.ts | 18 ++--- .../backend/src/core/UserKeypairStoreService.ts | 6 +- .../src/core/activitypub/ApDbResolverService.ts | 10 +-- .../backend/src/core/entities/UserEntityService.ts | 6 +- packages/backend/src/misc/cache.ts | 89 +++++++++++++++++++++- .../queue/processors/DeliverProcessorService.ts | 6 +- .../backend/src/server/NodeinfoServerService.ts | 4 +- .../backend/src/server/api/AuthenticateService.ts | 6 +- 15 files changed, 137 insertions(+), 52 deletions(-) (limited to 'packages/backend/src/core/NoteCreateService.ts') diff --git a/packages/backend/src/core/CustomEmojiService.ts b/packages/backend/src/core/CustomEmojiService.ts index b404848d7d..a62854c61c 100644 --- a/packages/backend/src/core/CustomEmojiService.ts +++ b/packages/backend/src/core/CustomEmojiService.ts @@ -8,7 +8,7 @@ import type { DriveFile } from '@/models/entities/DriveFile.js'; import type { Emoji } from '@/models/entities/Emoji.js'; import type { EmojisRepository, Note } from '@/models/index.js'; import { bindThis } from '@/decorators.js'; -import { Cache } from '@/misc/cache.js'; +import { KVCache } from '@/misc/cache.js'; import { UtilityService } from '@/core/UtilityService.js'; import type { Config } from '@/config.js'; import { ReactionService } from '@/core/ReactionService.js'; @@ -16,7 +16,7 @@ import { query } from '@/misc/prelude/url.js'; @Injectable() export class CustomEmojiService { - private cache: Cache; + private cache: KVCache; constructor( @Inject(DI.config) @@ -34,7 +34,7 @@ export class CustomEmojiService { private globalEventService: GlobalEventService, private reactionService: ReactionService, ) { - this.cache = new Cache(1000 * 60 * 60 * 12); + this.cache = new KVCache(1000 * 60 * 60 * 12); } @bindThis diff --git a/packages/backend/src/core/FederatedInstanceService.ts b/packages/backend/src/core/FederatedInstanceService.ts index e83b037dd7..b85791e43f 100644 --- a/packages/backend/src/core/FederatedInstanceService.ts +++ b/packages/backend/src/core/FederatedInstanceService.ts @@ -1,7 +1,7 @@ import { Inject, Injectable } from '@nestjs/common'; import type { InstancesRepository } from '@/models/index.js'; import type { Instance } from '@/models/entities/Instance.js'; -import { Cache } from '@/misc/cache.js'; +import { KVCache } from '@/misc/cache.js'; import { IdService } from '@/core/IdService.js'; import { DI } from '@/di-symbols.js'; import { UtilityService } from '@/core/UtilityService.js'; @@ -9,7 +9,7 @@ import { bindThis } from '@/decorators.js'; @Injectable() export class FederatedInstanceService { - private cache: Cache; + private cache: KVCache; constructor( @Inject(DI.instancesRepository) @@ -18,7 +18,7 @@ export class FederatedInstanceService { private utilityService: UtilityService, private idService: IdService, ) { - this.cache = new Cache(1000 * 60 * 60); + this.cache = new KVCache(1000 * 60 * 60); } @bindThis diff --git a/packages/backend/src/core/InstanceActorService.ts b/packages/backend/src/core/InstanceActorService.ts index ee9ae0733f..ef87051a74 100644 --- a/packages/backend/src/core/InstanceActorService.ts +++ b/packages/backend/src/core/InstanceActorService.ts @@ -2,7 +2,7 @@ import { Inject, Injectable } from '@nestjs/common'; import { IsNull } from 'typeorm'; import type { LocalUser } from '@/models/entities/User.js'; import type { UsersRepository } from '@/models/index.js'; -import { Cache } from '@/misc/cache.js'; +import { KVCache } from '@/misc/cache.js'; import { DI } from '@/di-symbols.js'; import { CreateSystemUserService } from '@/core/CreateSystemUserService.js'; import { bindThis } from '@/decorators.js'; @@ -11,7 +11,7 @@ const ACTOR_USERNAME = 'instance.actor' as const; @Injectable() export class InstanceActorService { - private cache: Cache; + private cache: KVCache; constructor( @Inject(DI.usersRepository) @@ -19,7 +19,7 @@ export class InstanceActorService { private createSystemUserService: CreateSystemUserService, ) { - this.cache = new Cache(Infinity); + this.cache = new KVCache(Infinity); } @bindThis diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts index 10d74e4218..b9bb0bcbd0 100644 --- a/packages/backend/src/core/NoteCreateService.ts +++ b/packages/backend/src/core/NoteCreateService.ts @@ -19,7 +19,7 @@ import { isDuplicateKeyValueError } from '@/misc/is-duplicate-key-value-error.js import { checkWordMute } from '@/misc/check-word-mute.js'; import type { Channel } from '@/models/entities/Channel.js'; import { normalizeForSearch } from '@/misc/normalize-for-search.js'; -import { Cache } from '@/misc/cache.js'; +import { KVCache } from '@/misc/cache.js'; import type { UserProfile } from '@/models/entities/UserProfile.js'; import { RelayService } from '@/core/RelayService.js'; import { FederatedInstanceService } from '@/core/FederatedInstanceService.js'; @@ -46,7 +46,7 @@ import { DB_MAX_NOTE_TEXT_LENGTH } from '@/const.js'; import { RoleService } from '@/core/RoleService.js'; import { MetaService } from '@/core/MetaService.js'; -const mutedWordsCache = new Cache<{ userId: UserProfile['userId']; mutedWords: UserProfile['mutedWords']; }[]>(1000 * 60 * 5); +const mutedWordsCache = new KVCache<{ userId: UserProfile['userId']; mutedWords: UserProfile['mutedWords']; }[]>(1000 * 60 * 5); type NotificationType = 'reply' | 'renote' | 'quote' | 'mention'; diff --git a/packages/backend/src/core/RelayService.ts b/packages/backend/src/core/RelayService.ts index 86f983cc78..4537f1b81a 100644 --- a/packages/backend/src/core/RelayService.ts +++ b/packages/backend/src/core/RelayService.ts @@ -3,7 +3,7 @@ import { IsNull } from 'typeorm'; import type { LocalUser, User } from '@/models/entities/User.js'; import type { RelaysRepository, UsersRepository } from '@/models/index.js'; import { IdService } from '@/core/IdService.js'; -import { Cache } from '@/misc/cache.js'; +import { KVCache } from '@/misc/cache.js'; import type { Relay } from '@/models/entities/Relay.js'; import { QueueService } from '@/core/QueueService.js'; import { CreateSystemUserService } from '@/core/CreateSystemUserService.js'; @@ -16,7 +16,7 @@ const ACTOR_USERNAME = 'relay.actor' as const; @Injectable() export class RelayService { - private relaysCache: Cache; + private relaysCache: KVCache; constructor( @Inject(DI.usersRepository) @@ -30,7 +30,7 @@ export class RelayService { private createSystemUserService: CreateSystemUserService, private apRendererService: ApRendererService, ) { - this.relaysCache = new Cache(1000 * 60 * 10); + this.relaysCache = new KVCache(1000 * 60 * 10); } @bindThis diff --git a/packages/backend/src/core/RoleService.ts b/packages/backend/src/core/RoleService.ts index bb7680f4e5..7b63e43cb1 100644 --- a/packages/backend/src/core/RoleService.ts +++ b/packages/backend/src/core/RoleService.ts @@ -2,7 +2,7 @@ import { Inject, Injectable } from '@nestjs/common'; import Redis from 'ioredis'; import { In } from 'typeorm'; import type { Role, RoleAssignment, RoleAssignmentsRepository, RolesRepository, UsersRepository } from '@/models/index.js'; -import { Cache } from '@/misc/cache.js'; +import { KVCache } from '@/misc/cache.js'; import type { User } from '@/models/entities/User.js'; import { DI } from '@/di-symbols.js'; import { bindThis } from '@/decorators.js'; @@ -57,8 +57,8 @@ export const DEFAULT_POLICIES: RolePolicies = { @Injectable() export class RoleService implements OnApplicationShutdown { - private rolesCache: Cache; - private roleAssignmentByUserIdCache: Cache; + private rolesCache: KVCache; + private roleAssignmentByUserIdCache: KVCache; public static AlreadyAssignedError = class extends Error {}; public static NotAssignedError = class extends Error {}; @@ -84,8 +84,8 @@ export class RoleService implements OnApplicationShutdown { ) { //this.onMessage = this.onMessage.bind(this); - this.rolesCache = new Cache(Infinity); - this.roleAssignmentByUserIdCache = new Cache(Infinity); + this.rolesCache = new KVCache(Infinity); + this.roleAssignmentByUserIdCache = new KVCache(Infinity); this.redisSubscriber.on('message', this.onMessage); } diff --git a/packages/backend/src/core/UserBlockingService.ts b/packages/backend/src/core/UserBlockingService.ts index 92408da342..33b51537a6 100644 --- a/packages/backend/src/core/UserBlockingService.ts +++ b/packages/backend/src/core/UserBlockingService.ts @@ -15,7 +15,7 @@ import { ApRendererService } from '@/core/activitypub/ApRendererService.js'; import { LoggerService } from '@/core/LoggerService.js'; import { WebhookService } from '@/core/WebhookService.js'; import { bindThis } from '@/decorators.js'; -import { Cache } from '@/misc/cache.js'; +import { KVCache } from '@/misc/cache.js'; import { StreamMessages } from '@/server/api/stream/types.js'; @Injectable() @@ -23,7 +23,7 @@ export class UserBlockingService implements OnApplicationShutdown { private logger: Logger; // キーがユーザーIDで、値がそのユーザーがブロックしているユーザーのIDのリストなキャッシュ - private blockingsByUserIdCache: Cache; + private blockingsByUserIdCache: KVCache; constructor( @Inject(DI.redisSubscriber) @@ -58,7 +58,7 @@ export class UserBlockingService implements OnApplicationShutdown { ) { this.logger = this.loggerService.getLogger('user-block'); - this.blockingsByUserIdCache = new Cache(Infinity); + this.blockingsByUserIdCache = new KVCache(Infinity); this.redisSubscriber.on('message', this.onMessage); } diff --git a/packages/backend/src/core/UserCacheService.ts b/packages/backend/src/core/UserCacheService.ts index fc383d1c08..631eb44062 100644 --- a/packages/backend/src/core/UserCacheService.ts +++ b/packages/backend/src/core/UserCacheService.ts @@ -1,7 +1,7 @@ import { Inject, Injectable } from '@nestjs/common'; import Redis from 'ioredis'; import type { UsersRepository } from '@/models/index.js'; -import { Cache } from '@/misc/cache.js'; +import { KVCache } from '@/misc/cache.js'; import type { LocalUser, User } from '@/models/entities/User.js'; import { DI } from '@/di-symbols.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; @@ -11,10 +11,10 @@ import type { OnApplicationShutdown } from '@nestjs/common'; @Injectable() export class UserCacheService implements OnApplicationShutdown { - public userByIdCache: Cache; - public localUserByNativeTokenCache: Cache; - public localUserByIdCache: Cache; - public uriPersonCache: Cache; + public userByIdCache: KVCache; + public localUserByNativeTokenCache: KVCache; + public localUserByIdCache: KVCache; + public uriPersonCache: KVCache; constructor( @Inject(DI.redisSubscriber) @@ -27,10 +27,10 @@ export class UserCacheService implements OnApplicationShutdown { ) { //this.onMessage = this.onMessage.bind(this); - this.userByIdCache = new Cache(Infinity); - this.localUserByNativeTokenCache = new Cache(Infinity); - this.localUserByIdCache = new Cache(Infinity); - this.uriPersonCache = new Cache(Infinity); + this.userByIdCache = new KVCache(Infinity); + this.localUserByNativeTokenCache = new KVCache(Infinity); + this.localUserByIdCache = new KVCache(Infinity); + this.uriPersonCache = new KVCache(Infinity); this.redisSubscriber.on('message', this.onMessage); } diff --git a/packages/backend/src/core/UserKeypairStoreService.ts b/packages/backend/src/core/UserKeypairStoreService.ts index 1d3cc87c8d..61c9293f86 100644 --- a/packages/backend/src/core/UserKeypairStoreService.ts +++ b/packages/backend/src/core/UserKeypairStoreService.ts @@ -1,20 +1,20 @@ import { Inject, Injectable } from '@nestjs/common'; import type { User } from '@/models/entities/User.js'; import type { UserKeypairsRepository } from '@/models/index.js'; -import { Cache } from '@/misc/cache.js'; +import { KVCache } from '@/misc/cache.js'; import type { UserKeypair } from '@/models/entities/UserKeypair.js'; import { DI } from '@/di-symbols.js'; import { bindThis } from '@/decorators.js'; @Injectable() export class UserKeypairStoreService { - private cache: Cache; + private cache: KVCache; constructor( @Inject(DI.userKeypairsRepository) private userKeypairsRepository: UserKeypairsRepository, ) { - this.cache = new Cache(Infinity); + this.cache = new KVCache(Infinity); } @bindThis diff --git a/packages/backend/src/core/activitypub/ApDbResolverService.ts b/packages/backend/src/core/activitypub/ApDbResolverService.ts index d0a4ad7a75..c3b3875613 100644 --- a/packages/backend/src/core/activitypub/ApDbResolverService.ts +++ b/packages/backend/src/core/activitypub/ApDbResolverService.ts @@ -3,7 +3,7 @@ import escapeRegexp from 'escape-regexp'; import { DI } from '@/di-symbols.js'; import type { NotesRepository, UserPublickeysRepository, UsersRepository } from '@/models/index.js'; import type { Config } from '@/config.js'; -import { Cache } from '@/misc/cache.js'; +import { KVCache } from '@/misc/cache.js'; import type { UserPublickey } from '@/models/entities/UserPublickey.js'; import { UserCacheService } from '@/core/UserCacheService.js'; import type { Note } from '@/models/entities/Note.js'; @@ -31,8 +31,8 @@ export type UriParseResult = { @Injectable() export class ApDbResolverService { - private publicKeyCache: Cache; - private publicKeyByUserIdCache: Cache; + private publicKeyCache: KVCache; + private publicKeyByUserIdCache: KVCache; constructor( @Inject(DI.config) @@ -50,8 +50,8 @@ export class ApDbResolverService { private userCacheService: UserCacheService, private apPersonService: ApPersonService, ) { - this.publicKeyCache = new Cache(Infinity); - this.publicKeyByUserIdCache = new Cache(Infinity); + this.publicKeyCache = new KVCache(Infinity); + this.publicKeyByUserIdCache = new KVCache(Infinity); } @bindThis diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts index 068ffad09d..b693883e06 100644 --- a/packages/backend/src/core/entities/UserEntityService.ts +++ b/packages/backend/src/core/entities/UserEntityService.ts @@ -8,7 +8,7 @@ import type { Packed } from '@/misc/json-schema.js'; import type { Promiseable } from '@/misc/prelude/await-all.js'; import { awaitAll } from '@/misc/prelude/await-all.js'; import { USER_ACTIVE_THRESHOLD, USER_ONLINE_THRESHOLD } from '@/const.js'; -import { Cache } from '@/misc/cache.js'; +import { KVCache } from '@/misc/cache.js'; import type { Instance } from '@/models/entities/Instance.js'; import type { LocalUser, RemoteUser, User } from '@/models/entities/User.js'; import { birthdaySchema, descriptionSchema, localUsernameSchema, locationSchema, nameSchema, passwordSchema } from '@/models/entities/User.js'; @@ -52,7 +52,7 @@ export class UserEntityService implements OnModuleInit { private customEmojiService: CustomEmojiService; private antennaService: AntennaService; private roleService: RoleService; - private userInstanceCache: Cache; + private userInstanceCache: KVCache; constructor( private moduleRef: ModuleRef, @@ -121,7 +121,7 @@ export class UserEntityService implements OnModuleInit { //private antennaService: AntennaService, //private roleService: RoleService, ) { - this.userInstanceCache = new Cache(1000 * 60 * 60 * 3); + this.userInstanceCache = new KVCache(1000 * 60 * 60 * 3); } onModuleInit() { diff --git a/packages/backend/src/misc/cache.ts b/packages/backend/src/misc/cache.ts index 43a71a2b57..b249cf4480 100644 --- a/packages/backend/src/misc/cache.ts +++ b/packages/backend/src/misc/cache.ts @@ -2,11 +2,11 @@ import { bindThis } from '@/decorators.js'; // TODO: メモリ節約のためあまり参照されないキーを定期的に削除できるようにする? -export class Cache { +export class KVCache { public cache: Map; private lifetime: number; - constructor(lifetime: Cache['lifetime']) { + constructor(lifetime: KVCache['lifetime']) { this.cache = new Map(); this.lifetime = lifetime; } @@ -87,3 +87,88 @@ export class Cache { return value; } } + +export class Cache { + private cachedAt: number | null = null; + private value: T | undefined; + private lifetime: number; + + constructor(lifetime: Cache['lifetime']) { + this.lifetime = lifetime; + } + + @bindThis + public set(value: T): void { + this.cachedAt = Date.now(); + this.value = value; + } + + @bindThis + public get(): T | undefined { + if (this.cachedAt == null) return undefined; + if ((Date.now() - this.cachedAt) > this.lifetime) { + this.value = undefined; + this.cachedAt = null; + return undefined; + } + return this.value; + } + + @bindThis + public delete() { + this.value = undefined; + this.cachedAt = null; + } + + /** + * キャッシュがあればそれを返し、無ければfetcherを呼び出して結果をキャッシュ&返します + * optional: キャッシュが存在してもvalidatorでfalseを返すとキャッシュ無効扱いにします + */ + @bindThis + public async fetch(fetcher: () => Promise, validator?: (cachedValue: T) => boolean): Promise { + const cachedValue = this.get(); + if (cachedValue !== undefined) { + if (validator) { + if (validator(cachedValue)) { + // Cache HIT + return cachedValue; + } + } else { + // Cache HIT + return cachedValue; + } + } + + // Cache MISS + const value = await fetcher(); + this.set(value); + return value; + } + + /** + * キャッシュがあればそれを返し、無ければfetcherを呼び出して結果をキャッシュ&返します + * optional: キャッシュが存在してもvalidatorでfalseを返すとキャッシュ無効扱いにします + */ + @bindThis + public async fetchMaybe(fetcher: () => Promise, validator?: (cachedValue: T) => boolean): Promise { + const cachedValue = this.get(); + if (cachedValue !== undefined) { + if (validator) { + if (validator(cachedValue)) { + // Cache HIT + return cachedValue; + } + } else { + // Cache HIT + return cachedValue; + } + } + + // Cache MISS + const value = await fetcher(); + if (value !== undefined) { + this.set(value); + } + return value; + } +} diff --git a/packages/backend/src/queue/processors/DeliverProcessorService.ts b/packages/backend/src/queue/processors/DeliverProcessorService.ts index 43a92bb267..34e1ddfc84 100644 --- a/packages/backend/src/queue/processors/DeliverProcessorService.ts +++ b/packages/backend/src/queue/processors/DeliverProcessorService.ts @@ -7,7 +7,7 @@ import { MetaService } from '@/core/MetaService.js'; import { ApRequestService } from '@/core/activitypub/ApRequestService.js'; import { FederatedInstanceService } from '@/core/FederatedInstanceService.js'; import { FetchInstanceMetadataService } from '@/core/FetchInstanceMetadataService.js'; -import { Cache } from '@/misc/cache.js'; +import { KVCache } from '@/misc/cache.js'; import type { Instance } from '@/models/entities/Instance.js'; import InstanceChart from '@/core/chart/charts/instance.js'; import ApRequestChart from '@/core/chart/charts/ap-request.js'; @@ -22,7 +22,7 @@ import type { DeliverJobData } from '../types.js'; @Injectable() export class DeliverProcessorService { private logger: Logger; - private suspendedHostsCache: Cache; + private suspendedHostsCache: KVCache; private latest: string | null; constructor( @@ -46,7 +46,7 @@ export class DeliverProcessorService { private queueLoggerService: QueueLoggerService, ) { this.logger = this.queueLoggerService.logger.createSubLogger('deliver'); - this.suspendedHostsCache = new Cache(1000 * 60 * 60); + this.suspendedHostsCache = new KVCache(1000 * 60 * 60); } @bindThis diff --git a/packages/backend/src/server/NodeinfoServerService.ts b/packages/backend/src/server/NodeinfoServerService.ts index 364b46696d..86019d4166 100644 --- a/packages/backend/src/server/NodeinfoServerService.ts +++ b/packages/backend/src/server/NodeinfoServerService.ts @@ -4,7 +4,7 @@ import type { NotesRepository, UsersRepository } from '@/models/index.js'; import type { Config } from '@/config.js'; import { MetaService } from '@/core/MetaService.js'; import { MAX_NOTE_TEXT_LENGTH } from '@/const.js'; -import { Cache } from '@/misc/cache.js'; +import { KVCache } from '@/misc/cache.js'; import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { bindThis } from '@/decorators.js'; import NotesChart from '@/core/chart/charts/notes.js'; @@ -118,7 +118,7 @@ export class NodeinfoServerService { }; }; - const cache = new Cache>>(1000 * 60 * 10); + const cache = new KVCache>>(1000 * 60 * 10); fastify.get(nodeinfo2_1path, async (request, reply) => { const base = await cache.fetch(null, () => nodeinfo2()); diff --git a/packages/backend/src/server/api/AuthenticateService.ts b/packages/backend/src/server/api/AuthenticateService.ts index 87438c348d..a1895e3705 100644 --- a/packages/backend/src/server/api/AuthenticateService.ts +++ b/packages/backend/src/server/api/AuthenticateService.ts @@ -3,7 +3,7 @@ import { DI } from '@/di-symbols.js'; import type { AccessTokensRepository, AppsRepository, UsersRepository } from '@/models/index.js'; import type { LocalUser } from '@/models/entities/User.js'; import type { AccessToken } from '@/models/entities/AccessToken.js'; -import { Cache } from '@/misc/cache.js'; +import { KVCache } from '@/misc/cache.js'; import type { App } from '@/models/entities/App.js'; import { UserCacheService } from '@/core/UserCacheService.js'; import isNativeToken from '@/misc/is-native-token.js'; @@ -18,7 +18,7 @@ export class AuthenticationError extends Error { @Injectable() export class AuthenticateService { - private appCache: Cache; + private appCache: KVCache; constructor( @Inject(DI.usersRepository) @@ -32,7 +32,7 @@ export class AuthenticateService { private userCacheService: UserCacheService, ) { - this.appCache = new Cache(Infinity); + this.appCache = new KVCache(Infinity); } @bindThis -- cgit v1.2.3-freya From 31f3f5f0f04b438b7cf12295303dc9adde28f82f Mon Sep 17 00:00:00 2001 From: syuilo Date: Fri, 24 Mar 2023 19:08:08 +0900 Subject: enhance(backend): リモートサーバーのチャート生成を無効にするオプションを追加 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + locales/ja-JP.yml | 1 + ...9652081809-enableChartsForFederatedInstances.js | 11 +++++++++ packages/backend/src/core/DriveService.ts | 8 +++++-- packages/backend/src/core/NoteCreateService.ts | 6 +++-- packages/backend/src/core/NoteDeleteService.ts | 6 +++-- packages/backend/src/core/UserFollowingService.ts | 26 +++++++++++++++------- .../src/core/activitypub/models/ApPersonService.ts | 10 +++++++-- packages/backend/src/models/entities/Meta.ts | 5 +++++ .../queue/processors/DeliverProcessorService.ts | 11 ++++++--- .../src/queue/processors/InboxProcessorService.ts | 5 ++++- .../backend/src/server/api/endpoints/admin/meta.ts | 5 +++++ .../src/server/api/endpoints/admin/update-meta.ts | 5 +++++ packages/frontend/src/pages/admin/settings.vue | 7 ++++++ 14 files changed, 87 insertions(+), 20 deletions(-) create mode 100644 packages/backend/migration/1679652081809-enableChartsForFederatedInstances.js (limited to 'packages/backend/src/core/NoteCreateService.ts') diff --git a/CHANGELOG.md b/CHANGELOG.md index e89f0ca707..1c792b537b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ ### Server - リモートユーザーのチャート生成を無効にするオプションを追加 +- リモートサーバーのチャート生成を無効にするオプションを追加 - ドライブのチャートはローカルユーザーのみ生成するように - 空のアンテナが作成できるのを修正 diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 356b93c696..cf4ede30b6 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -981,6 +981,7 @@ retryAllQueuesNow: "すべてのキューを今すぐ再試行" retryAllQueuesConfirmTitle: "今すぐ再試行しますか?" retryAllQueuesConfirmText: "一時的にサーバーの負荷が増大することがあります。" enableChartsForRemoteUser: "リモートユーザーのチャートを生成" +enableChartsForFederatedInstances: "リモートサーバーのチャートを生成" showClipButtonInNoteFooter: "ノートのアクションにクリップを追加" _achievements: diff --git a/packages/backend/migration/1679652081809-enableChartsForFederatedInstances.js b/packages/backend/migration/1679652081809-enableChartsForFederatedInstances.js new file mode 100644 index 0000000000..0733339841 --- /dev/null +++ b/packages/backend/migration/1679652081809-enableChartsForFederatedInstances.js @@ -0,0 +1,11 @@ +export class enableChartsForFederatedInstances1679652081809 { + name = 'enableChartsForFederatedInstances1679652081809' + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" ADD "enableChartsForFederatedInstances" boolean NOT NULL DEFAULT true`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "enableChartsForFederatedInstances"`); + } +} diff --git a/packages/backend/src/core/DriveService.ts b/packages/backend/src/core/DriveService.ts index 7e991cfd9e..c6258474ec 100644 --- a/packages/backend/src/core/DriveService.ts +++ b/packages/backend/src/core/DriveService.ts @@ -624,7 +624,9 @@ export class DriveService { // ローカルユーザーのみ this.perUserDriveChart.update(file, true); } else { - this.instanceChart.updateDrive(file, true); + if ((await this.metaService.fetch()).enableChartsForFederatedInstances) { + this.instanceChart.updateDrive(file, true); + } } return file; @@ -712,7 +714,9 @@ export class DriveService { // ローカルユーザーのみ this.perUserDriveChart.update(file, false); } else { - this.instanceChart.updateDrive(file, false); + if ((await this.metaService.fetch()).enableChartsForFederatedInstances) { + this.instanceChart.updateDrive(file, false); + } } } diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts index b9bb0bcbd0..7d08053761 100644 --- a/packages/backend/src/core/NoteCreateService.ts +++ b/packages/backend/src/core/NoteCreateService.ts @@ -444,9 +444,11 @@ export class NoteCreateService implements OnApplicationShutdown { // Register host if (this.userEntityService.isRemoteUser(user)) { - this.federatedInstanceService.fetch(user.host).then(i => { + this.federatedInstanceService.fetch(user.host).then(async i => { this.instancesRepository.increment({ id: i.id }, 'notesCount', 1); - this.instanceChart.updateNote(i.host, note, true); + if ((await this.metaService.fetch()).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 93cb68bbfe..dd878f7bba 100644 --- a/packages/backend/src/core/NoteDeleteService.ts +++ b/packages/backend/src/core/NoteDeleteService.ts @@ -105,9 +105,11 @@ export class NoteDeleteService { } if (this.userEntityService.isRemoteUser(user)) { - this.federatedInstanceService.fetch(user.host).then(i => { + this.federatedInstanceService.fetch(user.host).then(async i => { this.instancesRepository.decrement({ id: i.id }, 'notesCount', 1); - this.instanceChart.updateNote(i.host, note, false); + if ((await this.metaService.fetch()).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 1c85504353..b51b553c70 100644 --- a/packages/backend/src/core/UserFollowingService.ts +++ b/packages/backend/src/core/UserFollowingService.ts @@ -17,6 +17,7 @@ import { UserEntityService } from '@/core/entities/UserEntityService.js'; import { ApRendererService } from '@/core/activitypub/ApRendererService.js'; import { bindThis } from '@/decorators.js'; import { UserBlockingService } from '@/core/UserBlockingService.js'; +import { MetaService } from '@/core/MetaService.js'; import Logger from '../logger.js'; const logger = new Logger('following/create'); @@ -57,6 +58,7 @@ export class UserFollowingService { private idService: IdService, private queueService: QueueService, private globalEventService: GlobalEventService, + private metaService: MetaService, private notificationService: NotificationService, private federatedInstanceService: FederatedInstanceService, private webhookService: WebhookService, @@ -200,14 +202,18 @@ export class UserFollowingService { //#region Update instance stats if (this.userEntityService.isRemoteUser(follower) && this.userEntityService.isLocalUser(followee)) { - this.federatedInstanceService.fetch(follower.host).then(i => { + this.federatedInstanceService.fetch(follower.host).then(async i => { this.instancesRepository.increment({ id: i.id }, 'followingCount', 1); - this.instanceChart.updateFollowing(i.host, true); + if ((await this.metaService.fetch()).enableChartsForFederatedInstances) { + this.instanceChart.updateFollowing(i.host, true); + } }); } else if (this.userEntityService.isLocalUser(follower) && this.userEntityService.isRemoteUser(followee)) { - this.federatedInstanceService.fetch(followee.host).then(i => { + this.federatedInstanceService.fetch(followee.host).then(async i => { this.instancesRepository.increment({ id: i.id }, 'followersCount', 1); - this.instanceChart.updateFollowers(i.host, true); + if ((await this.metaService.fetch()).enableChartsForFederatedInstances) { + this.instanceChart.updateFollowers(i.host, true); + } }); } //#endregion @@ -320,14 +326,18 @@ export class UserFollowingService { //#region Update instance stats if (this.userEntityService.isRemoteUser(follower) && this.userEntityService.isLocalUser(followee)) { - this.federatedInstanceService.fetch(follower.host).then(i => { + this.federatedInstanceService.fetch(follower.host).then(async i => { this.instancesRepository.decrement({ id: i.id }, 'followingCount', 1); - this.instanceChart.updateFollowing(i.host, false); + if ((await this.metaService.fetch()).enableChartsForFederatedInstances) { + this.instanceChart.updateFollowing(i.host, false); + } }); } else if (this.userEntityService.isLocalUser(follower) && this.userEntityService.isRemoteUser(followee)) { - this.federatedInstanceService.fetch(followee.host).then(i => { + this.federatedInstanceService.fetch(followee.host).then(async i => { this.instancesRepository.decrement({ id: i.id }, 'followersCount', 1); - this.instanceChart.updateFollowers(i.host, false); + if ((await this.metaService.fetch()).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 d06958da0c..41f7eafa41 100644 --- a/packages/backend/src/core/activitypub/models/ApPersonService.ts +++ b/packages/backend/src/core/activitypub/models/ApPersonService.ts @@ -30,6 +30,7 @@ import { StatusError } from '@/misc/status-error.js'; import type { UtilityService } from '@/core/UtilityService.js'; import type { UserEntityService } from '@/core/entities/UserEntityService.js'; import { bindThis } from '@/decorators.js'; +import { MetaService } from '@/core/MetaService.js'; import { getApId, getApType, getOneApHrefNullable, isActor, isCollection, isCollectionOrOrderedCollection, isPropertyValue } from '../type.js'; import { extractApHashtags } from './tag.js'; import type { OnModuleInit } from '@nestjs/common'; @@ -50,6 +51,7 @@ export class ApPersonService implements OnModuleInit { private userEntityService: UserEntityService; private idService: IdService; private globalEventService: GlobalEventService; + private metaService: MetaService; private federatedInstanceService: FederatedInstanceService; private fetchInstanceMetadataService: FetchInstanceMetadataService; private userCacheService: UserCacheService; @@ -92,6 +94,7 @@ export class ApPersonService implements OnModuleInit { //private userEntityService: UserEntityService, //private idService: IdService, //private globalEventService: GlobalEventService, + //private metaService: MetaService, //private federatedInstanceService: FederatedInstanceService, //private fetchInstanceMetadataService: FetchInstanceMetadataService, //private userCacheService: UserCacheService, @@ -112,6 +115,7 @@ export class ApPersonService implements OnModuleInit { this.userEntityService = this.moduleRef.get('UserEntityService'); this.idService = this.moduleRef.get('IdService'); this.globalEventService = this.moduleRef.get('GlobalEventService'); + this.metaService = this.moduleRef.get('MetaService'); this.federatedInstanceService = this.moduleRef.get('FederatedInstanceService'); this.fetchInstanceMetadataService = this.moduleRef.get('FetchInstanceMetadataService'); this.userCacheService = this.moduleRef.get('UserCacheService'); @@ -327,10 +331,12 @@ export class ApPersonService implements OnModuleInit { } // Register host - this.federatedInstanceService.fetch(host).then(i => { + this.federatedInstanceService.fetch(host).then(async i => { this.instancesRepository.increment({ id: i.id }, 'usersCount', 1); - this.instanceChart.newUser(i.host); this.fetchInstanceMetadataService.fetchInstanceMetadata(i); + if ((await this.metaService.fetch()).enableChartsForFederatedInstances) { + this.instanceChart.newUser(i.host); + } }); this.usersChart.update(user!, true); diff --git a/packages/backend/src/models/entities/Meta.ts b/packages/backend/src/models/entities/Meta.ts index c7c60b6405..2e4f90b57f 100644 --- a/packages/backend/src/models/entities/Meta.ts +++ b/packages/backend/src/models/entities/Meta.ts @@ -396,6 +396,11 @@ export class Meta { }) public enableChartsForRemoteUser: boolean; + @Column('boolean', { + default: true, + }) + public enableChartsForFederatedInstances: boolean; + @Column('jsonb', { default: { }, }) diff --git a/packages/backend/src/queue/processors/DeliverProcessorService.ts b/packages/backend/src/queue/processors/DeliverProcessorService.ts index 34e1ddfc84..f637bf8818 100644 --- a/packages/backend/src/queue/processors/DeliverProcessorService.ts +++ b/packages/backend/src/queue/processors/DeliverProcessorService.ts @@ -88,10 +88,12 @@ export class DeliverProcessorService { } this.fetchInstanceMetadataService.fetchInstanceMetadata(i); - - this.instanceChart.requestSent(i.host, true); this.apRequestChart.deliverSucc(); this.federationChart.deliverd(i.host, true); + + if (meta.enableChartsForFederatedInstances) { + this.instanceChart.requestSent(i.host, true); + } }); return 'Success'; @@ -107,9 +109,12 @@ export class DeliverProcessorService { }); } - this.instanceChart.requestSent(i.host, false); this.apRequestChart.deliverFail(); this.federationChart.deliverd(i.host, false); + + if (meta.enableChartsForFederatedInstances) { + this.instanceChart.requestSent(i.host, false); + } }); if (res instanceof StatusError) { diff --git a/packages/backend/src/queue/processors/InboxProcessorService.ts b/packages/backend/src/queue/processors/InboxProcessorService.ts index 41fe06b7c3..ed7f38d013 100644 --- a/packages/backend/src/queue/processors/InboxProcessorService.ts +++ b/packages/backend/src/queue/processors/InboxProcessorService.ts @@ -184,9 +184,12 @@ export class InboxProcessorService { this.fetchInstanceMetadataService.fetchInstanceMetadata(i); - this.instanceChart.requestReceived(i.host); this.apRequestChart.inbox(); this.federationChart.inbox(i.host); + + if (meta.enableChartsForFederatedInstances) { + this.instanceChart.requestReceived(i.host); + } }); // アクティビティを処理 diff --git a/packages/backend/src/server/api/endpoints/admin/meta.ts b/packages/backend/src/server/api/endpoints/admin/meta.ts index cf21e1bd8f..fc318a621a 100644 --- a/packages/backend/src/server/api/endpoints/admin/meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/meta.ts @@ -243,6 +243,10 @@ export const meta = { type: 'boolean', optional: false, nullable: false, }, + enableChartsForFederatedInstances: { + type: 'boolean', + optional: false, nullable: false, + }, policies: { type: 'object', optional: false, nullable: false, @@ -341,6 +345,7 @@ export default class extends Endpoint { enableIpLogging: instance.enableIpLogging, enableActiveEmailValidation: instance.enableActiveEmailValidation, enableChartsForRemoteUser: instance.enableChartsForRemoteUser, + enableChartsForFederatedInstances: instance.enableChartsForFederatedInstances, policies: { ...DEFAULT_POLICIES, ...instance.policies }, }; }); 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 78a398d6b5..11de29bf83 100644 --- a/packages/backend/src/server/api/endpoints/admin/update-meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/update-meta.ts @@ -93,6 +93,7 @@ export const paramDef = { enableIpLogging: { type: 'boolean' }, enableActiveEmailValidation: { type: 'boolean' }, enableChartsForRemoteUser: { type: 'boolean' }, + enableChartsForFederatedInstances: { type: 'boolean' }, }, required: [], } as const; @@ -382,6 +383,10 @@ export default class extends Endpoint { set.enableChartsForRemoteUser = ps.enableChartsForRemoteUser; } + if (ps.enableChartsForFederatedInstances !== undefined) { + set.enableChartsForFederatedInstances = ps.enableChartsForFederatedInstances; + } + await this.metaService.update(set); this.moderationLogService.insertModerationLog(me, 'updateMeta'); }); diff --git a/packages/frontend/src/pages/admin/settings.vue b/packages/frontend/src/pages/admin/settings.vue index ce6a14600c..65e64930d5 100644 --- a/packages/frontend/src/pages/admin/settings.vue +++ b/packages/frontend/src/pages/admin/settings.vue @@ -47,6 +47,10 @@ + + + + @@ -180,6 +184,7 @@ let enableRegistration: boolean = $ref(false); let emailRequiredForSignup: boolean = $ref(false); let enableServiceWorker: boolean = $ref(false); let enableChartsForRemoteUser: boolean = $ref(false); +let enableChartsForFederatedInstances: boolean = $ref(false); let swPublicKey: any = $ref(null); let swPrivateKey: any = $ref(null); let deeplAuthKey: string = $ref(''); @@ -204,6 +209,7 @@ async function init() { emailRequiredForSignup = meta.emailRequiredForSignup; enableServiceWorker = meta.enableServiceWorker; enableChartsForRemoteUser = meta.enableChartsForRemoteUser; + enableChartsForFederatedInstances = meta.enableChartsForFederatedInstances; swPublicKey = meta.swPublickey; swPrivateKey = meta.swPrivateKey; deeplAuthKey = meta.deeplAuthKey; @@ -229,6 +235,7 @@ function save() { emailRequiredForSignup, enableServiceWorker, enableChartsForRemoteUser, + enableChartsForFederatedInstances, swPublicKey, swPrivateKey, deeplAuthKey, -- cgit v1.2.3-freya