]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/commitdiff
Fix actor follow counts calculation
authorChocobozzz <me@florianbigard.com>
Wed, 13 Oct 2021 14:18:42 +0000 (16:18 +0200)
committerChocobozzz <me@florianbigard.com>
Wed, 13 Oct 2021 14:18:42 +0000 (16:18 +0200)
server/lib/activitypub/process/process-follow.ts
server/lib/actor-follow-health-cache.ts
server/models/actor/actor-follow.ts
server/tests/api/server/auto-follows.ts
server/tests/api/server/jobs.ts

index f85238f8e73ba50635ea9f174fb2f51373ab5216..5562f079891764e9e1efdbcf89881231a5179797 100644 (file)
@@ -48,12 +48,14 @@ async function processFollow (byActor: MActorSignature, activityId: string, targ
       return { actorFollow: undefined as MActorFollowActors }
     }
 
-    const [ actorFollow, created ] = await ActorFollowModel.findOrCreate<MActorFollowActors>({
-      where: {
-        actorId: byActor.id,
-        targetActorId: targetActor.id
-      },
-      defaults: {
+    // Don't use findOrCreate by sequelize that breaks our actor follow hooks
+    let created = false
+    let actorFollow: MActorFollowActors = await ActorFollowModel.loadByActorAndTarget(byActor.id, targetActor.id, t)
+
+    if (!actorFollow) {
+      created = true
+
+      actorFollow = await ActorFollowModel.create({
         actorId: byActor.id,
         targetActorId: targetActor.id,
         url: activityId,
@@ -61,9 +63,8 @@ async function processFollow (byActor: MActorSignature, activityId: string, targ
         state: CONFIG.FOLLOWERS.INSTANCE.MANUAL_APPROVAL
           ? 'pending'
           : 'accepted'
-      },
-      transaction: t
-    })
+      }, { transaction: t })
+    }
 
     // Set the follow as accepted if the remote actor follows a channel or account
     // Or if the instance automatically accepts followers
index ab8cc98df810f0a69473c0d7a533afd8c5d7563b..34357a97a640649135115cc0e89634ffcb26f77d 100644 (file)
@@ -12,7 +12,7 @@ class ActorFollowHealthCache {
   private pendingBadServer = new Set<number>()
   private pendingGoodServer = new Set<number>()
 
-  private badInboxes = new Set<string>()
+  private readonly badInboxes = new Set<string>()
 
   private constructor () {}
 
index 283856d3ffa73b3482997400cdde6f9cc74dc4d4..95bb2df56626f0383f43c25048aed6561ab0155d 100644 (file)
@@ -19,6 +19,7 @@ import {
   UpdatedAt
 } from 'sequelize-typescript'
 import { isActivityPubUrlValid } from '@server/helpers/custom-validators/activitypub/misc'
+import { afterCommitIfTransaction } from '@server/helpers/database-utils'
 import { getServerActor } from '@server/models/application/application'
 import {
   MActorFollowActorsDefault,
@@ -118,20 +119,22 @@ export class ActorFollowModel extends Model<Partial<AttributesOnly<ActorFollowMo
   @AfterCreate
   @AfterUpdate
   static incrementFollowerAndFollowingCount (instance: ActorFollowModel, options: any) {
-    if (instance.state !== 'accepted') return undefined
-
-    return Promise.all([
-      ActorModel.rebuildFollowsCount(instance.actorId, 'following', options.transaction),
-      ActorModel.rebuildFollowsCount(instance.targetActorId, 'followers', options.transaction)
-    ])
+    return afterCommitIfTransaction(options.transaction, () => {
+      return Promise.all([
+        ActorModel.rebuildFollowsCount(instance.actorId, 'following'),
+        ActorModel.rebuildFollowsCount(instance.targetActorId, 'followers')
+      ])
+    })
   }
 
   @AfterDestroy
   static decrementFollowerAndFollowingCount (instance: ActorFollowModel, options: any) {
-    return Promise.all([
-      ActorModel.rebuildFollowsCount(instance.actorId, 'following', options.transaction),
-      ActorModel.rebuildFollowsCount(instance.targetActorId, 'followers', options.transaction)
-    ])
+    return afterCommitIfTransaction(options.transaction, () => {
+      return Promise.all([
+        ActorModel.rebuildFollowsCount(instance.actorId, 'following'),
+        ActorModel.rebuildFollowsCount(instance.targetActorId, 'followers')
+      ])
+    })
   }
 
   static removeFollowsOf (actorId: number, t?: Transaction) {
index ce7b519252517f490bcf891aa31cce117798e8ad..ca6475bd52e311157c875c4523db288dd1c076bd 100644 (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 follow = body.data.find(f => f.follower.host === follower.host && f.state === 'accepted')
 
-    if (exists === true) expect(follow).to.exist
-    else expect(follow).to.be.undefined
+    if (exists === true) expect(follow, `Follower ${follower.url} should exist on ${following.url}`).to.exist
+    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 follow = body.data.find(f => f.following.host === following.host && f.state === 'accepted')
 
-    if (exists === true) expect(follow).to.exist
-    else expect(follow).to.be.undefined
+    if (exists === true) expect(follow, `Following ${following.url} should exist on ${follower.url}`).to.exist
+    else expect(follow, `Following ${following.url} should not exist on ${follower.url}`).to.be.undefined
   }
 }
 
index 937028e4f710d2f0dde3573a6bf6500bc1dc801e..8c4e012265cd28ac9bbe77f289ab36272d768718 100644 (file)
@@ -88,8 +88,6 @@ describe('Test jobs', function () {
     const jobs = body.data
     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
   })