normalize userFollowingsCache / userFollowersCache and add hibernatedUserCache to reduce the number of cache-clears and allow use of caching in many more places
This commit is contained in:
parent
372714c9b6
commit
fa68751a19
28 changed files with 816 additions and 581 deletions
|
|
@ -147,12 +147,7 @@ export class UserFollowingService implements OnModuleInit {
|
|||
if (blocked) throw new IdentifiableError('3338392a-f764-498d-8855-db939dcf8c48', 'blocked');
|
||||
}
|
||||
|
||||
if (await this.followingsRepository.exists({
|
||||
where: {
|
||||
followerId: follower.id,
|
||||
followeeId: followee.id,
|
||||
},
|
||||
})) {
|
||||
if (await this.cacheService.isFollowing(follower, followee)) {
|
||||
// すでにフォロー関係が存在している場合
|
||||
if (this.userEntityService.isRemoteUser(follower) && this.userEntityService.isLocalUser(followee)) {
|
||||
// リモート → ローカル: acceptを送り返しておしまい
|
||||
|
|
@ -180,24 +175,14 @@ export class UserFollowingService implements OnModuleInit {
|
|||
let autoAccept = false;
|
||||
|
||||
// 鍵アカウントであっても、既にフォローされていた場合はスルー
|
||||
const isFollowing = await this.followingsRepository.exists({
|
||||
where: {
|
||||
followerId: follower.id,
|
||||
followeeId: followee.id,
|
||||
},
|
||||
});
|
||||
const isFollowing = await this.cacheService.isFollowing(follower, followee);
|
||||
if (isFollowing) {
|
||||
autoAccept = true;
|
||||
}
|
||||
|
||||
// フォローしているユーザーは自動承認オプション
|
||||
if (!autoAccept && (this.userEntityService.isLocalUser(followee) && followeeProfile.autoAcceptFollowed)) {
|
||||
const isFollowed = await this.followingsRepository.exists({
|
||||
where: {
|
||||
followerId: followee.id,
|
||||
followeeId: follower.id,
|
||||
},
|
||||
});
|
||||
const isFollowed = await this.cacheService.isFollowing(followee, follower); // intentionally reversed parameters
|
||||
|
||||
if (isFollowed) autoAccept = true;
|
||||
}
|
||||
|
|
@ -206,12 +191,7 @@ export class UserFollowingService implements OnModuleInit {
|
|||
if (followee.isLocked && !autoAccept) {
|
||||
autoAccept = !!(await this.accountMoveService.validateAlsoKnownAs(
|
||||
follower,
|
||||
(oldSrc, newSrc) => this.followingsRepository.exists({
|
||||
where: {
|
||||
followeeId: followee.id,
|
||||
followerId: newSrc.id,
|
||||
},
|
||||
}),
|
||||
(oldSrc, newSrc) => this.cacheService.isFollowing(newSrc, followee),
|
||||
true,
|
||||
));
|
||||
}
|
||||
|
|
@ -366,32 +346,29 @@ export class UserFollowingService implements OnModuleInit {
|
|||
},
|
||||
silent = false,
|
||||
): Promise<void> {
|
||||
const following = await this.followingsRepository.findOne({
|
||||
relations: {
|
||||
follower: true,
|
||||
followee: true,
|
||||
},
|
||||
where: {
|
||||
followerId: follower.id,
|
||||
followeeId: followee.id,
|
||||
},
|
||||
});
|
||||
const [
|
||||
followerUser,
|
||||
followeeUser,
|
||||
following,
|
||||
] = await Promise.all([
|
||||
this.cacheService.findUserById(follower.id),
|
||||
this.cacheService.findUserById(followee.id),
|
||||
this.cacheService.userFollowingsCache.fetch(follower.id).then(fs => fs.get(followee.id)),
|
||||
]);
|
||||
|
||||
if (following === null || !following.follower || !following.followee) {
|
||||
if (following == null) {
|
||||
this.logger.warn('フォロー解除がリクエストされましたがフォローしていませんでした');
|
||||
return;
|
||||
}
|
||||
|
||||
await this.followingsRepository.delete(following.id);
|
||||
await this.internalEventService.emit('unfollow', { followerId: follower.id, followeeId: followee.id });
|
||||
|
||||
// Handled by CacheService
|
||||
// this.cacheService.userFollowingsCache.refresh(follower.id);
|
||||
|
||||
this.decrementFollowing(following.follower, following.followee);
|
||||
this.decrementFollowing(followerUser, followeeUser);
|
||||
|
||||
if (!silent && this.userEntityService.isLocalUser(follower)) {
|
||||
// Publish unfollow event
|
||||
this.userEntityService.pack(followee.id, follower, {
|
||||
this.userEntityService.pack(followeeUser, follower, {
|
||||
schema: 'UserDetailedNotMe',
|
||||
}).then(async packed => {
|
||||
this.globalEventService.publishMainStream(follower.id, 'unfollow', packed);
|
||||
|
|
@ -416,8 +393,6 @@ export class UserFollowingService implements OnModuleInit {
|
|||
follower: MiUser,
|
||||
followee: MiUser,
|
||||
): Promise<void> {
|
||||
await this.internalEventService.emit('unfollow', { followerId: follower.id, followeeId: followee.id });
|
||||
|
||||
// Neither followee nor follower has moved.
|
||||
if (!follower.movedToUri && !followee.movedToUri) {
|
||||
//#region Decrement following / followers counts
|
||||
|
|
@ -691,22 +666,22 @@ export class UserFollowingService implements OnModuleInit {
|
|||
*/
|
||||
@bindThis
|
||||
private async removeFollow(followee: Both, follower: Both): Promise<void> {
|
||||
const following = await this.followingsRepository.findOne({
|
||||
relations: {
|
||||
followee: true,
|
||||
follower: true,
|
||||
},
|
||||
where: {
|
||||
followeeId: followee.id,
|
||||
followerId: follower.id,
|
||||
},
|
||||
});
|
||||
const [
|
||||
followerUser,
|
||||
followeeUser,
|
||||
following,
|
||||
] = await Promise.all([
|
||||
this.cacheService.findUserById(follower.id),
|
||||
this.cacheService.findUserById(followee.id),
|
||||
this.cacheService.userFollowingsCache.fetch(follower.id).then(fs => fs.get(followee.id)),
|
||||
]);
|
||||
|
||||
if (!following || !following.followee || !following.follower) return;
|
||||
if (!following) return;
|
||||
|
||||
await this.followingsRepository.delete(following.id);
|
||||
await this.internalEventService.emit('unfollow', { followerId: follower.id, followeeId: followee.id });
|
||||
|
||||
this.decrementFollowing(following.follower, following.followee);
|
||||
this.decrementFollowing(followerUser, followeeUser);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -737,36 +712,26 @@ export class UserFollowingService implements OnModuleInit {
|
|||
}
|
||||
|
||||
@bindThis
|
||||
public getFollowees(userId: MiUser['id']) {
|
||||
return this.followingsRepository.createQueryBuilder('following')
|
||||
.select('following.followeeId')
|
||||
.where('following.followerId = :followerId', { followerId: userId })
|
||||
.getMany();
|
||||
public async getFollowees(userId: MiUser['id']) {
|
||||
const followings = await this.cacheService.userFollowingsCache.fetch(userId);
|
||||
return Array.from(followings.values());
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public isFollowing(followerId: MiUser['id'], followeeId: MiUser['id']) {
|
||||
return this.followingsRepository.exists({
|
||||
where: {
|
||||
followerId,
|
||||
followeeId,
|
||||
},
|
||||
});
|
||||
public async isFollowing(followerId: MiUser['id'], followeeId: MiUser['id']) {
|
||||
return this.cacheService.isFollowing(followerId, followeeId);
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async isMutual(aUserId: MiUser['id'], bUserId: MiUser['id']) {
|
||||
const count = await this.followingsRepository.createQueryBuilder('following')
|
||||
.where(new Brackets(qb => {
|
||||
qb.where('following.followerId = :aUserId', { aUserId })
|
||||
.andWhere('following.followeeId = :bUserId', { bUserId });
|
||||
}))
|
||||
.orWhere(new Brackets(qb => {
|
||||
qb.where('following.followerId = :bUserId', { bUserId })
|
||||
.andWhere('following.followeeId = :aUserId', { aUserId });
|
||||
}))
|
||||
.getCount();
|
||||
const [
|
||||
isFollowing,
|
||||
isFollowed,
|
||||
] = await Promise.all([
|
||||
this.isFollowing(aUserId, bUserId),
|
||||
this.isFollowing(bUserId, aUserId),
|
||||
]);
|
||||
|
||||
return count === 2;
|
||||
return isFollowing && isFollowed;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue