mirror of
https://codeberg.org/yeentown/barkey.git
synced 2025-07-07 20:44:34 +00:00
persist changes to meta host lists to instance table
This commit is contained in:
parent
373c60b521
commit
305250d073
1 changed files with 53 additions and 2 deletions
|
@ -4,7 +4,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { DataSource } from 'typeorm';
|
import { DataSource, EntityManager } from 'typeorm';
|
||||||
import * as Redis from 'ioredis';
|
import * as Redis from 'ioredis';
|
||||||
import { DI } from '@/di-symbols.js';
|
import { DI } from '@/di-symbols.js';
|
||||||
import { MiMeta } from '@/models/Meta.js';
|
import { MiMeta } from '@/models/Meta.js';
|
||||||
|
@ -12,6 +12,8 @@ import { GlobalEventService } from '@/core/GlobalEventService.js';
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import type { GlobalEvents } from '@/core/GlobalEventService.js';
|
import type { GlobalEvents } from '@/core/GlobalEventService.js';
|
||||||
import { FeaturedService } from '@/core/FeaturedService.js';
|
import { FeaturedService } from '@/core/FeaturedService.js';
|
||||||
|
import { MiInstance } from '@/models/Instance.js';
|
||||||
|
import { diffArrays } from '@/misc/diff-arrays.js';
|
||||||
import type { OnApplicationShutdown } from '@nestjs/common';
|
import type { OnApplicationShutdown } from '@nestjs/common';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -103,7 +105,7 @@ export class MetaService implements OnApplicationShutdown {
|
||||||
let before: MiMeta | undefined;
|
let before: MiMeta | undefined;
|
||||||
|
|
||||||
const updated = await this.db.transaction(async transactionalEntityManager => {
|
const updated = await this.db.transaction(async transactionalEntityManager => {
|
||||||
const metas = await transactionalEntityManager.find(MiMeta, {
|
const metas: (MiMeta | undefined)[] = await transactionalEntityManager.find(MiMeta, {
|
||||||
order: {
|
order: {
|
||||||
id: 'DESC',
|
id: 'DESC',
|
||||||
},
|
},
|
||||||
|
@ -126,6 +128,10 @@ export class MetaService implements OnApplicationShutdown {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Propagate changes to blockedHosts, silencedHosts, mediaSilencedHosts, federationInstances, and bubbleInstances to the relevant instance rows
|
||||||
|
// Do this inside the transaction to avoid potential race condition (when an instance gets registered while we're updating).
|
||||||
|
await this.persistBlocks(transactionalEntityManager, before ?? {}, afters[0]);
|
||||||
|
|
||||||
return afters[0];
|
return afters[0];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -159,4 +165,49 @@ export class MetaService implements OnApplicationShutdown {
|
||||||
public onApplicationShutdown(signal?: string | undefined): void {
|
public onApplicationShutdown(signal?: string | undefined): void {
|
||||||
this.dispose();
|
this.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async persistBlocks(tem: EntityManager, before: Partial<MiMeta>, after: Partial<MiMeta>): Promise<void> {
|
||||||
|
await this.persistBlock(tem, before.blockedHosts, after.blockedHosts, 'isBlocked');
|
||||||
|
await this.persistBlock(tem, before.silencedHosts, after.silencedHosts, 'isSilenced');
|
||||||
|
await this.persistBlock(tem, before.mediaSilencedHosts, after.mediaSilencedHosts, 'isMediaSilenced');
|
||||||
|
await this.persistBlock(tem, before.federationHosts, after.federationHosts, 'isAllowListed');
|
||||||
|
await this.persistBlock(tem, before.bubbleInstances, after.bubbleInstances, 'isBubbled');
|
||||||
|
}
|
||||||
|
|
||||||
|
private async persistBlock(tem: EntityManager, before: string[] | undefined, after: string[] | undefined, field: keyof MiInstance): Promise<void> {
|
||||||
|
const { added, removed } = diffArrays(before, after);
|
||||||
|
|
||||||
|
if (removed.length > 0) {
|
||||||
|
await this.updateInstancesByHost(tem, field, false, removed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (added.length > 0) {
|
||||||
|
await this.updateInstancesByHost(tem, field, true, added);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async updateInstancesByHost(tem: EntityManager, field: keyof MiInstance, value: boolean, hosts: string[]): Promise<void> {
|
||||||
|
// Use non-array queries when possible, as they are indexed and can be much faster.
|
||||||
|
if (hosts.length === 1) {
|
||||||
|
const pattern = genHostPattern(hosts[0]);
|
||||||
|
await tem
|
||||||
|
.createQueryBuilder(MiInstance, 'instance')
|
||||||
|
.update()
|
||||||
|
.set({ [field]: value })
|
||||||
|
.where('(lower(reverse("host")) || \'.\') LIKE :pattern', { pattern })
|
||||||
|
.execute();
|
||||||
|
} else if (hosts.length > 1) {
|
||||||
|
const patterns = hosts.map(host => genHostPattern(host));
|
||||||
|
await tem
|
||||||
|
.createQueryBuilder(MiInstance, 'instance')
|
||||||
|
.update()
|
||||||
|
.set({ [field]: value })
|
||||||
|
.where('(lower(reverse("host")) || \'.\') LIKE ANY (:patterns)', {patterns})
|
||||||
|
.execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function genHostPattern(host: string): string {
|
||||||
|
return host.toLowerCase().split('').reverse().join('') + '.%';
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue