diff --git a/packages/backend/migration/1750217001651-enable-instance-HOT-updates.js b/packages/backend/migration/1750217001651-enable-instance-HOT-updates.js new file mode 100644 index 0000000000..995c3ed445 --- /dev/null +++ b/packages/backend/migration/1750217001651-enable-instance-HOT-updates.js @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: hazelnoot and other Sharkey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +// https://www.cybertec-postgresql.com/en/hot-updates-in-postgresql-for-better-performance/ + +/** + * @typedef {import('typeorm').MigrationInterface} MigrationInterface + */ + +/** + * @class + * @implements {MigrationInterface} + */ +export class EnableInstanceHOTUpdates1750217001651 { + name = 'EnableInstanceHOTUpdates1750217001651'; + + async up(queryRunner) { + await queryRunner.query(`ALTER TABLE "instance" SET (fillfactor = 50)`); + + // Vacuum can't run inside a transaction block, so query directly from the connection. + await queryRunner.connection.query(`VACUUM (FULL, VERBOSE) "instance"`); + } + + async down(queryRunner) { + await queryRunner.query(`ALTER TABLE "instance" SET (fillfactor = 100)`); + } +} diff --git a/packages/backend/src/core/FetchInstanceMetadataService.ts b/packages/backend/src/core/FetchInstanceMetadataService.ts index 0ba61ce4f9..855ecd7553 100644 --- a/packages/backend/src/core/FetchInstanceMetadataService.ts +++ b/packages/backend/src/core/FetchInstanceMetadataService.ts @@ -132,18 +132,21 @@ export class FetchInstanceMetadataService { } as Record; if (info) { - updates.softwareName = typeof info.software?.name === 'string' ? info.software.name.toLowerCase() : '?'; - updates.softwareVersion = info.software?.version; - updates.openRegistrations = info.openRegistrations; - updates.maintainerName = info.metadata ? info.metadata.maintainer ? (info.metadata.maintainer.name ?? null) : null : null; - updates.maintainerEmail = info.metadata ? info.metadata.maintainer ? (info.metadata.maintainer.email ?? null) : null : null; + const softwareName = typeof info.software?.name === 'string' ? info.software.name.toLowerCase() : '?'; + if (softwareName !== instance.softwareName) updates.softwareName = updates.softwareVersion = info.software?.version; + if (info.openRegistrations !== instance.openRegistrations) updates.openRegistrations = info.openRegistrations; + const maintainerName = info.metadata ? info.metadata.maintainer ? (info.metadata.maintainer.name ?? null) : null : null; + if (maintainerName !== instance.maintainerName) updates.maintainerName = maintainerName; + const maintainerEmail = info.metadata ? info.metadata.maintainer ? (info.metadata.maintainer.email ?? null) : null : null; + if (maintainerEmail !== instance.maintainerEmail) updates.maintainerEmail = maintainerEmail; } - if (name) updates.name = name; - if (description) updates.description = description; - if (icon ?? favicon) updates.iconUrl = (icon && !icon.includes('data:image/png;base64')) ? icon : favicon; - if (favicon) updates.faviconUrl = favicon; - if (themeColor) updates.themeColor = themeColor; + if (name !== instance.name) updates.name = name; + if (description !== instance.description) updates.description = description; + const iconUrl = (icon && !icon.includes('data:image/png;base64')) ? icon : favicon; + if (iconUrl !== instance.iconUrl) updates.iconUrl = iconUrl; + if (favicon !== instance.faviconUrl) updates.faviconUrl = favicon; + if (themeColor !== instance.themeColor) updates.themeColor = themeColor; await this.federatedInstanceService.update(instance.id, updates);