merge: Fix performance regression in URL previews (resoles #1091) (!1096)

View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/1096

Approved-by: dakkar <dakkar@thenautilus.net>
Approved-by: Marie <github@yuugi.dev>
This commit is contained in:
Marie 2025-06-06 20:09:28 +00:00
commit 24b0d7a376
5 changed files with 38 additions and 7 deletions

View file

@ -0,0 +1,16 @@
/*
* SPDX-FileCopyrightText: hazelnoot and other Sharkey contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
export class CreateIDXNoteUrl1749229288946 {
name = 'CreateIDXNoteUrl1749229288946'
async up(queryRunner) {
await queryRunner.query(`CREATE INDEX IF NOT EXISTS "IDX_note_url" ON "note" ("url") `);
}
async down(queryRunner) {
await queryRunner.query(`DROP INDEX "public"."IDX_note_url"`);
}
}

View file

@ -445,7 +445,11 @@ export class ApPersonService implements OnModuleInit, OnApplicationShutdown {
makeNotesFollowersOnlyBefore: (person as any).makeNotesFollowersOnlyBefore ?? null, makeNotesFollowersOnlyBefore: (person as any).makeNotesFollowersOnlyBefore ?? null,
makeNotesHiddenBefore: (person as any).makeNotesHiddenBefore ?? null, makeNotesHiddenBefore: (person as any).makeNotesHiddenBefore ?? null,
emojis, emojis,
attributionDomains: (Array.isArray(person.attributionDomains) && person.attributionDomains.every(x => typeof x === 'string')) ? person.attributionDomains : [], attributionDomains: Array.isArray(person.attributionDomains)
? person.attributionDomains
.filter((a: unknown) => typeof(a) === 'string' && a.length > 0 && a.length <= 128)
.slice(0, 32)
: [],
})) as MiRemoteUser; })) as MiRemoteUser;
let _description: string | null = null; let _description: string | null = null;
@ -629,7 +633,11 @@ export class ApPersonService implements OnModuleInit, OnApplicationShutdown {
// We use "!== false" to handle incorrect types, missing / null values, and "default to true" logic. // We use "!== false" to handle incorrect types, missing / null values, and "default to true" logic.
hideOnlineStatus: person.hideOnlineStatus !== false, hideOnlineStatus: person.hideOnlineStatus !== false,
isExplorable: person.discoverable !== false, isExplorable: person.discoverable !== false,
attributionDomains: (Array.isArray(person.attributionDomains) && person.attributionDomains.every(x => typeof x === 'string')) ? person.attributionDomains : [], attributionDomains: Array.isArray(person.attributionDomains)
? person.attributionDomains
.filter((a: unknown) => typeof(a) === 'string' && a.length > 0 && a.length <= 128)
.slice(0, 32)
: [],
...(await this.resolveAvatarAndBanner(exist, person.icon, person.image, person.backgroundUrl).catch(() => ({}))), ...(await this.resolveAvatarAndBanner(exist, person.icon, person.image, person.backgroundUrl).catch(() => ({}))),
} as Partial<MiRemoteUser> & Pick<MiRemoteUser, 'isBot' | 'isCat' | 'speakAsCat' | 'isLocked' | 'movedToUri' | 'alsoKnownAs' | 'isExplorable'>; } as Partial<MiRemoteUser> & Pick<MiRemoteUser, 'isBot' | 'isCat' | 'speakAsCat' | 'isLocked' | 'movedToUri' | 'alsoKnownAs' | 'isExplorable'>;

View file

@ -133,6 +133,7 @@ export class MiNote {
}) })
public uri: string | null; public uri: string | null;
@Index('IDX_note_url')
@Column('varchar', { @Column('varchar', {
length: 512, nullable: true, length: 512, nullable: true,
comment: 'The human readable url of a note. it will be null when the note is local.', comment: 'The human readable url of a note. it will be null when the note is local.',

View file

@ -390,9 +390,9 @@ export class MiUser {
}) })
public allowUnsignedFetch: UserUnsignedFetchOption; public allowUnsignedFetch: UserUnsignedFetchOption;
@Column('varchar', { @Column('text', {
name: 'attributionDomains', name: 'attributionDomains',
length: 128, array: true, default: '{}', array: true, default: '{}',
}) })
public attributionDomains: string[]; public attributionDomains: string[];

View file

@ -263,9 +263,15 @@ export const paramDef = {
enum: userUnsignedFetchOptions, enum: userUnsignedFetchOptions,
nullable: false, nullable: false,
}, },
attributionDomains: { type: 'array', items: { attributionDomains: {
type: 'array',
items: {
type: 'string', type: 'string',
} }, minLength: 1,
maxLength: 128,
},
maxLength: 32,
},
}, },
} as const; } as const;