1
0
Fork 0

Fix actor follow counts calculation

This commit is contained in:
Chocobozzz 2021-10-13 16:18:42 +02:00
parent f87d82b93d
commit 1cf0df024e
No known key found for this signature in database
GPG key ID: 583A612D890159BE
5 changed files with 28 additions and 26 deletions

View file

@ -48,12 +48,14 @@ async function processFollow (byActor: MActorSignature, activityId: string, targ
return { actorFollow: undefined as MActorFollowActors } return { actorFollow: undefined as MActorFollowActors }
} }
const [ actorFollow, created ] = await ActorFollowModel.findOrCreate<MActorFollowActors>({ // Don't use findOrCreate by sequelize that breaks our actor follow hooks
where: { let created = false
actorId: byActor.id, let actorFollow: MActorFollowActors = await ActorFollowModel.loadByActorAndTarget(byActor.id, targetActor.id, t)
targetActorId: targetActor.id
}, if (!actorFollow) {
defaults: { created = true
actorFollow = await ActorFollowModel.create({
actorId: byActor.id, actorId: byActor.id,
targetActorId: targetActor.id, targetActorId: targetActor.id,
url: activityId, url: activityId,
@ -61,9 +63,8 @@ async function processFollow (byActor: MActorSignature, activityId: string, targ
state: CONFIG.FOLLOWERS.INSTANCE.MANUAL_APPROVAL state: CONFIG.FOLLOWERS.INSTANCE.MANUAL_APPROVAL
? 'pending' ? 'pending'
: 'accepted' : 'accepted'
}, }, { transaction: t })
transaction: t }
})
// Set the follow as accepted if the remote actor follows a channel or account // Set the follow as accepted if the remote actor follows a channel or account
// Or if the instance automatically accepts followers // Or if the instance automatically accepts followers

View file

@ -12,7 +12,7 @@ class ActorFollowHealthCache {
private pendingBadServer = new Set<number>() private pendingBadServer = new Set<number>()
private pendingGoodServer = new Set<number>() private pendingGoodServer = new Set<number>()
private badInboxes = new Set<string>() private readonly badInboxes = new Set<string>()
private constructor () {} private constructor () {}

View file

@ -19,6 +19,7 @@ import {
UpdatedAt UpdatedAt
} from 'sequelize-typescript' } from 'sequelize-typescript'
import { isActivityPubUrlValid } from '@server/helpers/custom-validators/activitypub/misc' import { isActivityPubUrlValid } from '@server/helpers/custom-validators/activitypub/misc'
import { afterCommitIfTransaction } from '@server/helpers/database-utils'
import { getServerActor } from '@server/models/application/application' import { getServerActor } from '@server/models/application/application'
import { import {
MActorFollowActorsDefault, MActorFollowActorsDefault,
@ -118,20 +119,22 @@ export class ActorFollowModel extends Model<Partial<AttributesOnly<ActorFollowMo
@AfterCreate @AfterCreate
@AfterUpdate @AfterUpdate
static incrementFollowerAndFollowingCount (instance: ActorFollowModel, options: any) { static incrementFollowerAndFollowingCount (instance: ActorFollowModel, options: any) {
if (instance.state !== 'accepted') return undefined return afterCommitIfTransaction(options.transaction, () => {
return Promise.all([
return Promise.all([ ActorModel.rebuildFollowsCount(instance.actorId, 'following'),
ActorModel.rebuildFollowsCount(instance.actorId, 'following', options.transaction), ActorModel.rebuildFollowsCount(instance.targetActorId, 'followers')
ActorModel.rebuildFollowsCount(instance.targetActorId, 'followers', options.transaction) ])
]) })
} }
@AfterDestroy @AfterDestroy
static decrementFollowerAndFollowingCount (instance: ActorFollowModel, options: any) { static decrementFollowerAndFollowingCount (instance: ActorFollowModel, options: any) {
return Promise.all([ return afterCommitIfTransaction(options.transaction, () => {
ActorModel.rebuildFollowsCount(instance.actorId, 'following', options.transaction), return Promise.all([
ActorModel.rebuildFollowsCount(instance.targetActorId, 'followers', options.transaction) ActorModel.rebuildFollowsCount(instance.actorId, 'following'),
]) ActorModel.rebuildFollowsCount(instance.targetActorId, 'followers')
])
})
} }
static removeFollowsOf (actorId: number, t?: Transaction) { static removeFollowsOf (actorId: number, t?: Transaction) {

View file

@ -19,16 +19,16 @@ async function checkFollow (follower: PeerTubeServer, following: PeerTubeServer,
const body = await following.follows.getFollowers({ start: 0, count: 5, sort: '-createdAt' }) const body = await following.follows.getFollowers({ start: 0, count: 5, sort: '-createdAt' })
const follow = body.data.find(f => f.follower.host === follower.host && f.state === 'accepted') const follow = body.data.find(f => f.follower.host === follower.host && f.state === 'accepted')
if (exists === true) expect(follow).to.exist if (exists === true) expect(follow, `Follower ${follower.url} should exist on ${following.url}`).to.exist
else expect(follow).to.be.undefined else expect(follow, `Follower ${follower.url} should not exist on ${following.url}`).to.be.undefined
} }
{ {
const body = await follower.follows.getFollowings({ start: 0, count: 5, sort: '-createdAt' }) const body = await follower.follows.getFollowings({ start: 0, count: 5, sort: '-createdAt' })
const follow = body.data.find(f => f.following.host === following.host && f.state === 'accepted') const follow = body.data.find(f => f.following.host === following.host && f.state === 'accepted')
if (exists === true) expect(follow).to.exist if (exists === true) expect(follow, `Following ${following.url} should exist on ${follower.url}`).to.exist
else expect(follow).to.be.undefined else expect(follow, `Following ${following.url} should not exist on ${follower.url}`).to.be.undefined
} }
} }

View file

@ -88,8 +88,6 @@ describe('Test jobs', function () {
const jobs = body.data const jobs = body.data
expect(jobs).to.have.length.above(2) expect(jobs).to.have.length.above(2)
// We know there are a least 1 delayed job (video views) and 1 completed job (broadcast)
expect(jobs.find(j => j.state === 'delayed')).to.not.be.undefined
expect(jobs.find(j => j.state === 'completed')).to.not.be.undefined expect(jobs.find(j => j.state === 'completed')).to.not.be.undefined
}) })