deliver Delete activities to all known instances #198
2 changed files with 49 additions and 6 deletions
|
@ -8,6 +8,10 @@ interface IRecipe {
|
|||
type: string;
|
||||
}
|
||||
|
||||
interface IEveryoneRecipe extends IRecipe {
|
||||
type: 'Everyone';
|
||||
}
|
||||
|
||||
interface IFollowersRecipe extends IRecipe {
|
||||
type: 'Followers';
|
||||
}
|
||||
|
@ -17,6 +21,9 @@ interface IDirectRecipe extends IRecipe {
|
|||
to: IRemoteUser;
|
||||
}
|
||||
|
||||
const isEveryone = (recipe: any): recipe is IEveryoneRecipe =>
|
||||
recipe.type === 'Everyone';
|
||||
|
||||
const isFollowers = (recipe: any): recipe is IFollowersRecipe =>
|
||||
recipe.type === 'Followers';
|
||||
|
||||
|
@ -63,6 +70,13 @@ export default class DeliverManager {
|
|||
this.addRecipe(recipe);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add recipe to send this activity to all known sharedInboxes
|
||||
*/
|
||||
public addEveryone() {
|
||||
this.addRecipe({ type: 'Everyone' } as IEveryoneRecipe);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add recipe
|
||||
* @param recipe Recipe
|
||||
|
@ -82,9 +96,26 @@ export default class DeliverManager {
|
|||
/*
|
||||
build inbox list
|
||||
|
||||
Process follower recipes first to avoid duplication when processing
|
||||
direct recipes later.
|
||||
Processing order matters to avoid duplication.
|
||||
*/
|
||||
|
||||
if (this.recipes.some(r => isEveryone(r))) {
|
||||
// deliver to all of known network
|
||||
const sharedInboxes = await Users.createQueryBuilder('users')
|
||||
Johann150 marked this conversation as resolved
|
||||
.select('users.sharedInbox', 'sharedInbox')
|
||||
// so we don't have to make our inboxes Set work as hard
|
||||
.distinct(true)
|
||||
// can't deliver to unknown shared inbox
|
||||
.where('users.sharedInbox IS NOT NULL')
|
||||
// don't deliver to ourselves
|
||||
.andWhere('users.host IS NOT NULL')
|
||||
.getRawMany();
|
||||
|
||||
for (const inbox of sharedInboxes) {
|
||||
inboxes.add(inbox.sharedInbox);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.recipes.some(r => isFollowers(r))) {
|
||||
// followers deliver
|
||||
// TODO: SELECT DISTINCT ON ("followerSharedInbox") "followerSharedInbox" みたいな問い合わせにすればよりパフォーマンス向上できそう
|
||||
|
|
|
@ -10,7 +10,7 @@ import { User, ILocalUser, IRemoteUser } from '@/models/entities/user.js';
|
|||
import { Note } from '@/models/entities/note.js';
|
||||
import { Notes, Users, Instances } from '@/models/index.js';
|
||||
import { notesChart, perUserNotesChart, instanceChart } from '@/services/chart/index.js';
|
||||
import { deliverToFollowers, deliverToUser } from '@/remote/activitypub/deliver-manager.js';
|
||||
import DeliverManager from '@/remote/activitypub/deliver-manager.js';
|
||||
import { countSameRenotes } from '@/misc/count-same-renotes.js';
|
||||
import { isPureRenote } from '@/misc/renote.js';
|
||||
import { registerOrFetchInstanceDoc } from '../register-or-fetch-instance-doc.js';
|
||||
|
@ -132,10 +132,22 @@ async function getMentionedRemoteUsers(note: Note): Promise<IRemoteUser[]> {
|
|||
}
|
||||
|
||||
async function deliverToConcerned(user: { id: ILocalUser['id']; host: null; }, note: Note, content: any) {
|
||||
deliverToFollowers(user, content);
|
||||
deliverToRelays(user, content);
|
||||
const manager = new DeliverManager(user, content);
|
||||
|
||||
const remoteUsers = await getMentionedRemoteUsers(note);
|
||||
for (const remoteUser of remoteUsers) {
|
||||
deliverToUser(user, content, remoteUser);
|
||||
manager.addDirectRecipe(remoteUser);
|
||||
}
|
||||
|
||||
if (['public', 'home', 'followers'].includes(note.visibility)) {
|
||||
manager.addFollowersRecipe();
|
||||
}
|
||||
|
||||
if (['public', 'home'].includes(note.visibility)) {
|
||||
manager.addEveryone();
|
||||
}
|
||||
|
||||
await manager.execute();
|
||||
|
||||
deliverToRelays(user, content);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue
SELECT DISTINCT
would be preferable. Overall, it seems that target inboxes are not deduplicated.That is what the
groupBy
in line 111 was meant for. I didn't know, but just checked and there is.distinct(true)
available for query builders to achieveSELECT DISTINCT
. I'm not sure if it makes a difference toGROUP BY
.The overall deduplication is achieved because
inboxes
is aSet
and not an array.Best way to check that would be via Postgres
EXPLAIN ANALYZE
, I believe.I ran it myself but I also had a look at this Stackoverflow answer.
result of running
EXPLAIN ANALYZE
. tl;dr the query plans are identicalFrom the Stackoverflow answer:
Fun thing just happend, postgres 15 came out and...
Would be nice to see if we're affected.