wip: addAllKnowingSharedInbox
This commit is contained in:
parent
bb4af983b7
commit
1fc2ae025c
|
@ -9,10 +9,12 @@ import { DI } from '@/di-symbols.js';
|
||||||
import type { FollowingsRepository } from '@/models/_.js';
|
import type { FollowingsRepository } from '@/models/_.js';
|
||||||
import type { MiLocalUser, MiRemoteUser, MiUser } from '@/models/User.js';
|
import type { MiLocalUser, MiRemoteUser, MiUser } from '@/models/User.js';
|
||||||
import { QueueService } from '@/core/QueueService.js';
|
import { QueueService } from '@/core/QueueService.js';
|
||||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
|
||||||
import { bindThis } from '@/decorators.js';
|
import { bindThis } from '@/decorators.js';
|
||||||
import type { IActivity } from '@/core/activitypub/type.js';
|
import type { IActivity } from '@/core/activitypub/type.js';
|
||||||
import { ThinUser } from '@/queue/types.js';
|
import { ThinUser } from '@/queue/types.js';
|
||||||
|
import { AccountUpdateService } from '@/core/AccountUpdateService.js';
|
||||||
|
import type Logger from '@/logger.js';
|
||||||
|
import { ApLoggerService } from './ApLoggerService.js';
|
||||||
|
|
||||||
interface IRecipe {
|
interface IRecipe {
|
||||||
type: string;
|
type: string;
|
||||||
|
@ -27,12 +29,19 @@ interface IDirectRecipe extends IRecipe {
|
||||||
to: MiRemoteUser;
|
to: MiRemoteUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface IAllKnowingSharedInboxRecipe extends IRecipe {
|
||||||
|
type: 'AllKnowingSharedInbox';
|
||||||
|
}
|
||||||
|
|
||||||
const isFollowers = (recipe: IRecipe): recipe is IFollowersRecipe =>
|
const isFollowers = (recipe: IRecipe): recipe is IFollowersRecipe =>
|
||||||
recipe.type === 'Followers';
|
recipe.type === 'Followers';
|
||||||
|
|
||||||
const isDirect = (recipe: IRecipe): recipe is IDirectRecipe =>
|
const isDirect = (recipe: IRecipe): recipe is IDirectRecipe =>
|
||||||
recipe.type === 'Direct';
|
recipe.type === 'Direct';
|
||||||
|
|
||||||
|
const isAllKnowingSharedInbox = (recipe: IRecipe): recipe is IAllKnowingSharedInboxRecipe =>
|
||||||
|
recipe.type === 'AllKnowingSharedInbox';
|
||||||
|
|
||||||
class DeliverManager {
|
class DeliverManager {
|
||||||
private actor: ThinUser;
|
private actor: ThinUser;
|
||||||
private activity: IActivity | null;
|
private activity: IActivity | null;
|
||||||
|
@ -40,16 +49,15 @@ class DeliverManager {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param userEntityService
|
|
||||||
* @param followingsRepository
|
* @param followingsRepository
|
||||||
* @param queueService
|
* @param queueService
|
||||||
* @param actor Actor
|
* @param actor Actor
|
||||||
* @param activity Activity to deliver
|
* @param activity Activity to deliver
|
||||||
*/
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
private userEntityService: UserEntityService,
|
|
||||||
private followingsRepository: FollowingsRepository,
|
private followingsRepository: FollowingsRepository,
|
||||||
private queueService: QueueService,
|
private queueService: QueueService,
|
||||||
|
private logger: Logger,
|
||||||
|
|
||||||
actor: { id: MiUser['id']; host: null; },
|
actor: { id: MiUser['id']; host: null; },
|
||||||
activity: IActivity | null,
|
activity: IActivity | null,
|
||||||
|
@ -91,6 +99,18 @@ class DeliverManager {
|
||||||
this.addRecipe(recipe);
|
this.addRecipe(recipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add recipe for all-knowing shared inbox deliver
|
||||||
|
*/
|
||||||
|
@bindThis
|
||||||
|
public addAllKnowingSharedInboxRecipe(): void {
|
||||||
|
const deliver: IAllKnowingSharedInboxRecipe = {
|
||||||
|
type: 'AllKnowingSharedInbox',
|
||||||
|
};
|
||||||
|
|
||||||
|
this.addRecipe(deliver);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add recipe
|
* Add recipe
|
||||||
* @param recipe Recipe
|
* @param recipe Recipe
|
||||||
|
@ -105,10 +125,27 @@ class DeliverManager {
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
public async execute(): Promise<void> {
|
public async execute(): Promise<void> {
|
||||||
|
//#region collect inboxes by recipes
|
||||||
// The value flags whether it is shared or not.
|
// The value flags whether it is shared or not.
|
||||||
// key: inbox URL, value: whether it is sharedInbox
|
// key: inbox URL, value: whether it is sharedInbox
|
||||||
const inboxes = new Map<string, boolean>();
|
const inboxes = new Map<string, boolean>();
|
||||||
|
|
||||||
|
if (this.recipes.some(r => isAllKnowingSharedInbox(r))) {
|
||||||
|
// all-knowing shared inbox
|
||||||
|
const followings = await this.followingsRepository.find({
|
||||||
|
where: [
|
||||||
|
{ followerSharedInbox: Not(IsNull()) },
|
||||||
|
{ followeeSharedInbox: Not(IsNull()) },
|
||||||
|
],
|
||||||
|
select: ['followerSharedInbox', 'followeeSharedInbox'],
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const following of followings) {
|
||||||
|
if (following.followeeSharedInbox) inboxes.set(following.followeeSharedInbox, true);
|
||||||
|
if (following.followerSharedInbox) inboxes.set(following.followerSharedInbox, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// build inbox list
|
// build inbox list
|
||||||
// Process follower recipes first to avoid duplication when processing direct recipes later.
|
// Process follower recipes first to avoid duplication when processing direct recipes later.
|
||||||
if (this.recipes.some(r => isFollowers(r))) {
|
if (this.recipes.some(r => isFollowers(r))) {
|
||||||
|
@ -143,34 +180,40 @@ class DeliverManager {
|
||||||
|
|
||||||
inboxes.set(recipe.to.inbox, false);
|
inboxes.set(recipe.to.inbox, false);
|
||||||
}
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
// deliver
|
// deliver
|
||||||
await this.queueService.deliverMany(this.actor, this.activity, inboxes);
|
await this.queueService.deliverMany(this.actor, this.activity, inboxes);
|
||||||
|
this.logger.info(`Deliver queues dispatched: inboxes=${inboxes.size} actorId=${this.actor.id} activityId=${this.activity?.id}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ApDeliverManagerService {
|
export class ApDeliverManagerService {
|
||||||
|
private logger: Logger;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(DI.followingsRepository)
|
@Inject(DI.followingsRepository)
|
||||||
private followingsRepository: FollowingsRepository,
|
private followingsRepository: FollowingsRepository,
|
||||||
|
|
||||||
private userEntityService: UserEntityService,
|
|
||||||
private queueService: QueueService,
|
private queueService: QueueService,
|
||||||
|
private apLoggerService: ApLoggerService,
|
||||||
) {
|
) {
|
||||||
|
this.logger = this.apLoggerService.logger.createSubLogger('deliver-manager');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deliver activity to followers
|
* Deliver activity to followers
|
||||||
* @param actor
|
* @param actor
|
||||||
* @param activity Activity
|
* @param activity Activity
|
||||||
|
* @param forceMainKey Force to use main (rsa) key
|
||||||
*/
|
*/
|
||||||
@bindThis
|
@bindThis
|
||||||
public async deliverToFollowers(actor: { id: MiLocalUser['id']; host: null; }, activity: IActivity): Promise<void> {
|
public async deliverToFollowers(actor: { id: MiLocalUser['id']; host: null; }, activity: IActivity): Promise<void> {
|
||||||
const manager = new DeliverManager(
|
const manager = new DeliverManager(
|
||||||
this.userEntityService,
|
|
||||||
this.followingsRepository,
|
this.followingsRepository,
|
||||||
this.queueService,
|
this.queueService,
|
||||||
|
this.logger,
|
||||||
actor,
|
actor,
|
||||||
activity,
|
activity,
|
||||||
);
|
);
|
||||||
|
@ -187,9 +230,9 @@ export class ApDeliverManagerService {
|
||||||
@bindThis
|
@bindThis
|
||||||
public async deliverToUser(actor: { id: MiLocalUser['id']; host: null; }, activity: IActivity, to: MiRemoteUser): Promise<void> {
|
public async deliverToUser(actor: { id: MiLocalUser['id']; host: null; }, activity: IActivity, to: MiRemoteUser): Promise<void> {
|
||||||
const manager = new DeliverManager(
|
const manager = new DeliverManager(
|
||||||
this.userEntityService,
|
|
||||||
this.followingsRepository,
|
this.followingsRepository,
|
||||||
this.queueService,
|
this.queueService,
|
||||||
|
this.logger,
|
||||||
actor,
|
actor,
|
||||||
activity,
|
activity,
|
||||||
);
|
);
|
||||||
|
@ -206,9 +249,9 @@ export class ApDeliverManagerService {
|
||||||
@bindThis
|
@bindThis
|
||||||
public async deliverToUsers(actor: { id: MiLocalUser['id']; host: null; }, activity: IActivity, targets: MiRemoteUser[]): Promise<void> {
|
public async deliverToUsers(actor: { id: MiLocalUser['id']; host: null; }, activity: IActivity, targets: MiRemoteUser[]): Promise<void> {
|
||||||
const manager = new DeliverManager(
|
const manager = new DeliverManager(
|
||||||
this.userEntityService,
|
|
||||||
this.followingsRepository,
|
this.followingsRepository,
|
||||||
this.queueService,
|
this.queueService,
|
||||||
|
this.logger,
|
||||||
actor,
|
actor,
|
||||||
activity,
|
activity,
|
||||||
);
|
);
|
||||||
|
@ -219,10 +262,9 @@ export class ApDeliverManagerService {
|
||||||
@bindThis
|
@bindThis
|
||||||
public createDeliverManager(actor: { id: MiUser['id']; host: null; }, activity: IActivity | null): DeliverManager {
|
public createDeliverManager(actor: { id: MiUser['id']; host: null; }, activity: IActivity | null): DeliverManager {
|
||||||
return new DeliverManager(
|
return new DeliverManager(
|
||||||
this.userEntityService,
|
|
||||||
this.followingsRepository,
|
this.followingsRepository,
|
||||||
this.queueService,
|
this.queueService,
|
||||||
|
this.logger,
|
||||||
actor,
|
actor,
|
||||||
activity,
|
activity,
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue