Skip to content

Commit

Permalink
perf(backend): Defer instance metadata update (#727)
Browse files Browse the repository at this point in the history
  • Loading branch information
KOBA789 authored Sep 16, 2024
1 parent 8692712 commit 5138672
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 5 deletions.
15 changes: 14 additions & 1 deletion packages/backend/src/core/NoteCreateService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import { isReply } from '@/misc/is-reply.js';
import { trackPromise } from '@/misc/promise-tracker.js';
import { isNotNull } from '@/misc/is-not-null.js';
import { IdentifiableError } from '@/misc/identifiable-error.js';
import { CollapsedQueue } from '@/misc/collapsed-queue.js';

type NotificationType = 'reply' | 'renote' | 'quote' | 'mention';

Expand Down Expand Up @@ -150,6 +151,7 @@ type Option = {
export class NoteCreateService implements OnApplicationShutdown {
private logger: Logger;
#shutdownController = new AbortController();
private updateNotesCountQueue: CollapsedQueue<MiNote['id'], number>;

constructor(
@Inject(DI.config)
Expand Down Expand Up @@ -217,6 +219,7 @@ export class NoteCreateService implements OnApplicationShutdown {
private loggerService: LoggerService,
) {
this.logger = this.loggerService.getLogger('note:create');
this.updateNotesCountQueue = new CollapsedQueue(60 * 1000 * 5, this.collapseNotesCount, this.performUpdateNotesCount);
}

@bindThis
Expand Down Expand Up @@ -548,7 +551,7 @@ export class NoteCreateService implements OnApplicationShutdown {
// Register host
if (this.userEntityService.isRemoteUser(user)) {
this.federatedInstanceService.fetch(user.host).then(async i => {
this.instancesRepository.increment({ id: i.id }, 'notesCount', 1);
this.updateNotesCountQueue.enqueue(i.id, 1);
if ((await this.metaService.fetch()).enableChartsForFederatedInstances) {
this.instanceChart.updateNote(i.host, note, true);
}
Expand Down Expand Up @@ -1092,6 +1095,16 @@ export class NoteCreateService implements OnApplicationShutdown {
);
}

@bindThis
private collapseNotesCount(oldValue: number, newValue: number) {
return oldValue + newValue;
}

@bindThis
private performUpdateNotesCount(id: MiNote['id'], incrBy: number) {
this.instancesRepository.increment({ id: id }, 'notesCount', incrBy);
}

@bindThis
public dispose(): void {
this.#shutdownController.abort();
Expand Down
24 changes: 24 additions & 0 deletions packages/backend/src/misc/collapsed-queue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export class CollapsedQueue<K, V> {
private jobs: Map<K, V> = new Map();

constructor(
private timeout: number,
private collapse: (oldValue: V, newValue: V) => V,
private doJob: (key: K, value: V) => void,
) { }

enqueue(key: K, value: V) {
if (this.jobs.has(key)) {
const old = this.jobs.get(key)!;
const merged = this.collapse(old, value);
this.jobs.set(key, merged);
} else {
this.jobs.set(key, value);
setTimeout(() => {
const value = this.jobs.get(key)!;
this.jobs.delete(key);
this.doJob(key, value);
}, this.timeout);
}
}
}
22 changes: 18 additions & 4 deletions packages/backend/src/queue/processors/InboxProcessorService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@ import { bindThis } from '@/decorators.js';
import { IdentifiableError } from '@/misc/identifiable-error.js';
import { QueueLoggerService } from '../QueueLoggerService.js';
import type { InboxJobData } from '../types.js';
import { CollapsedQueue } from '@/misc/collapsed-queue.js';
import { MiNote } from '@/models/Note.js';

@Injectable()
export class InboxProcessorService {
private logger: Logger;
private updateInstanceQueue: CollapsedQueue<MiNote['id'], Date>;

constructor(
private utilityService: UtilityService,
Expand All @@ -48,6 +51,7 @@ export class InboxProcessorService {
private queueLoggerService: QueueLoggerService,
) {
this.logger = this.queueLoggerService.logger.createSubLogger('inbox');
this.updateInstanceQueue = new CollapsedQueue(60 * 1000 * 5, this.collapseUpdateInstanceJobs, this.performUpdateInstance);
}

@bindThis
Expand Down Expand Up @@ -180,10 +184,7 @@ export class InboxProcessorService {

// Update stats
this.federatedInstanceService.fetch(authUser.user.host).then(i => {
this.federatedInstanceService.update(i.id, {
latestRequestReceivedAt: new Date(),
isNotResponding: false,
});
this.updateInstanceQueue.enqueue(i.id, new Date());

this.fetchInstanceMetadataService.fetchInstanceMetadata(i);

Expand Down Expand Up @@ -211,4 +212,17 @@ export class InboxProcessorService {
}
return 'ok';
}

@bindThis
public collapseUpdateInstanceJobs(oldValue: Date, newValue: Date) {
return oldValue < newValue ? newValue : oldValue;
}

@bindThis
public performUpdateInstance(id: string, value: Date) {
this.federatedInstanceService.update(id, {
latestRequestReceivedAt: value,
isNotResponding: false,
});
}
}

0 comments on commit 5138672

Please sign in to comment.