fix(federation): avoid duplicate activity delivery (#8429)
* prefer shared inbox over individual inbox * no new shared inbox for direct recipes * fix type error
This commit is contained in:
		
							parent
							
								
									f7030d4a42
								
							
						
					
					
						commit
						1033e8e57f
					
				
					 1 changed files with 36 additions and 27 deletions
				
			
		|  | @ -79,37 +79,46 @@ export default class DeliverManager { | |||
| 
 | ||||
| 		const inboxes = new Set<string>(); | ||||
| 
 | ||||
| 		// build inbox list
 | ||||
| 		for (const recipe of this.recipes) { | ||||
| 			if (isFollowers(recipe)) { | ||||
| 				// followers deliver
 | ||||
| 				// TODO: SELECT DISTINCT ON ("followerSharedInbox") "followerSharedInbox" みたいな問い合わせにすればよりパフォーマンス向上できそう
 | ||||
| 				// ただ、sharedInboxがnullなリモートユーザーも稀におり、その対応ができなさそう?
 | ||||
| 				const followers = await Followings.find({ | ||||
| 					where: { | ||||
| 						followeeId: this.actor.id, | ||||
| 						followerHost: Not(IsNull()), | ||||
| 					}, | ||||
| 					select: { | ||||
| 						followerSharedInbox: true, | ||||
| 						followerInbox: true, | ||||
| 					}, | ||||
| 				}) as { | ||||
| 					followerSharedInbox: string | null; | ||||
| 					followerInbox: string; | ||||
| 				}[]; | ||||
| 		/* | ||||
| 		build inbox list | ||||
| 
 | ||||
| 				for (const following of followers) { | ||||
| 					const inbox = following.followerSharedInbox || following.followerInbox; | ||||
| 					inboxes.add(inbox); | ||||
| 				} | ||||
| 			} else if (isDirect(recipe)) { | ||||
| 				// direct deliver
 | ||||
| 				const inbox = recipe.to.inbox; | ||||
| 				if (inbox) inboxes.add(inbox); | ||||
| 		Process follower recipes first to avoid duplication when processing | ||||
| 		direct recipes later. | ||||
| 		*/ | ||||
| 		if (this.recipes.some(r => isFollowers(r)) { | ||||
| 			// followers deliver
 | ||||
| 			// TODO: SELECT DISTINCT ON ("followerSharedInbox") "followerSharedInbox" みたいな問い合わせにすればよりパフォーマンス向上できそう
 | ||||
| 			// ただ、sharedInboxがnullなリモートユーザーも稀におり、その対応ができなさそう?
 | ||||
| 			const followers = await Followings.find({ | ||||
| 				where: { | ||||
| 					followeeId: this.actor.id, | ||||
| 					followerHost: Not(IsNull()), | ||||
| 				}, | ||||
| 				select: { | ||||
| 					followerSharedInbox: true, | ||||
| 					followerInbox: true, | ||||
| 				}, | ||||
| 			}) as { | ||||
| 				followerSharedInbox: string | null; | ||||
| 				followerInbox: string; | ||||
| 			}[]; | ||||
| 
 | ||||
| 			for (const following of followers) { | ||||
| 				const inbox = following.followerSharedInbox || following.followerInbox; | ||||
| 				inboxes.add(inbox); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		this.recipes.filter((recipe): recipe is IDirectRecipe => { | ||||
| 			// followers recipes have already been processed
 | ||||
| 			isDirect(recipe) | ||||
| 			// check that shared inbox has not been added yet
 | ||||
| 			&& !(recipe.to.sharedInbox && inboxes.has(recipe.to.sharedInbox)) | ||||
| 			// check that they actually have an inbox
 | ||||
| 			&& recipe.to.inbox | ||||
| 		}) | ||||
| 		.forEach(recipe => inboxes.add(recipe.to.inbox)); | ||||
| 
 | ||||
| 		// deliver
 | ||||
| 		for (const inbox of inboxes) { | ||||
| 			deliver(this.actor, this.activity, inbox); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue