aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-10-13 16:18:42 +0200
committerChocobozzz <me@florianbigard.com>2021-10-13 16:18:42 +0200
commit1cf0df024e58432da39fe2d1b317fb5c9ab8bd2e (patch)
treea9e3e6e3330552fddda81688dd7ce69e099f0b05
parentf87d82b93d474d1290b3c641e63a39197193cb7e (diff)
downloadPeerTube-1cf0df024e58432da39fe2d1b317fb5c9ab8bd2e.tar.gz
PeerTube-1cf0df024e58432da39fe2d1b317fb5c9ab8bd2e.tar.zst
PeerTube-1cf0df024e58432da39fe2d1b317fb5c9ab8bd2e.zip
Fix actor follow counts calculation
-rw-r--r--server/lib/activitypub/process/process-follow.ts19
-rw-r--r--server/lib/actor-follow-health-cache.ts2
-rw-r--r--server/models/actor/actor-follow.ts23
-rw-r--r--server/tests/api/server/auto-follows.ts8
-rw-r--r--server/tests/api/server/jobs.ts2
5 files changed, 28 insertions, 26 deletions
diff --git a/server/lib/activitypub/process/process-follow.ts b/server/lib/activitypub/process/process-follow.ts
index f85238f8e..5562f0798 100644
--- a/server/lib/activitypub/process/process-follow.ts
+++ b/server/lib/activitypub/process/process-follow.ts
@@ -48,12 +48,14 @@ async function processFollow (byActor: MActorSignature, activityId: string, targ
48 return { actorFollow: undefined as MActorFollowActors } 48 return { actorFollow: undefined as MActorFollowActors }
49 } 49 }
50 50
51 const [ actorFollow, created ] = await ActorFollowModel.findOrCreate<MActorFollowActors>({ 51 // Don't use findOrCreate by sequelize that breaks our actor follow hooks
52 where: { 52 let created = false
53 actorId: byActor.id, 53 let actorFollow: MActorFollowActors = await ActorFollowModel.loadByActorAndTarget(byActor.id, targetActor.id, t)
54 targetActorId: targetActor.id 54
55 }, 55 if (!actorFollow) {
56 defaults: { 56 created = true
57
58 actorFollow = await ActorFollowModel.create({
57 actorId: byActor.id, 59 actorId: byActor.id,
58 targetActorId: targetActor.id, 60 targetActorId: targetActor.id,
59 url: activityId, 61 url: activityId,
@@ -61,9 +63,8 @@ async function processFollow (byActor: MActorSignature, activityId: string, targ
61 state: CONFIG.FOLLOWERS.INSTANCE.MANUAL_APPROVAL 63 state: CONFIG.FOLLOWERS.INSTANCE.MANUAL_APPROVAL
62 ? 'pending' 64 ? 'pending'
63 : 'accepted' 65 : 'accepted'
64 }, 66 }, { transaction: t })
65 transaction: t 67 }
66 })
67 68
68 // Set the follow as accepted if the remote actor follows a channel or account 69 // Set the follow as accepted if the remote actor follows a channel or account
69 // Or if the instance automatically accepts followers 70 // Or if the instance automatically accepts followers
diff --git a/server/lib/actor-follow-health-cache.ts b/server/lib/actor-follow-health-cache.ts
index ab8cc98df..34357a97a 100644
--- a/server/lib/actor-follow-health-cache.ts
+++ b/server/lib/actor-follow-health-cache.ts
@@ -12,7 +12,7 @@ class ActorFollowHealthCache {
12 private pendingBadServer = new Set<number>() 12 private pendingBadServer = new Set<number>()
13 private pendingGoodServer = new Set<number>() 13 private pendingGoodServer = new Set<number>()
14 14
15 private badInboxes = new Set<string>() 15 private readonly badInboxes = new Set<string>()
16 16
17 private constructor () {} 17 private constructor () {}
18 18
diff --git a/server/models/actor/actor-follow.ts b/server/models/actor/actor-follow.ts
index 283856d3f..95bb2df56 100644
--- a/server/models/actor/actor-follow.ts
+++ b/server/models/actor/actor-follow.ts
@@ -19,6 +19,7 @@ import {
19 UpdatedAt 19 UpdatedAt
20} from 'sequelize-typescript' 20} from 'sequelize-typescript'
21import { isActivityPubUrlValid } from '@server/helpers/custom-validators/activitypub/misc' 21import { isActivityPubUrlValid } from '@server/helpers/custom-validators/activitypub/misc'
22import { afterCommitIfTransaction } from '@server/helpers/database-utils'
22import { getServerActor } from '@server/models/application/application' 23import { getServerActor } from '@server/models/application/application'
23import { 24import {
24 MActorFollowActorsDefault, 25 MActorFollowActorsDefault,
@@ -118,20 +119,22 @@ export class ActorFollowModel extends Model<Partial<AttributesOnly<ActorFollowMo
118 @AfterCreate 119 @AfterCreate
119 @AfterUpdate 120 @AfterUpdate
120 static incrementFollowerAndFollowingCount (instance: ActorFollowModel, options: any) { 121 static incrementFollowerAndFollowingCount (instance: ActorFollowModel, options: any) {
121 if (instance.state !== 'accepted') return undefined 122 return afterCommitIfTransaction(options.transaction, () => {
122 123 return Promise.all([
123 return Promise.all([ 124 ActorModel.rebuildFollowsCount(instance.actorId, 'following'),
124 ActorModel.rebuildFollowsCount(instance.actorId, 'following', options.transaction), 125 ActorModel.rebuildFollowsCount(instance.targetActorId, 'followers')
125 ActorModel.rebuildFollowsCount(instance.targetActorId, 'followers', options.transaction) 126 ])
126 ]) 127 })
127 } 128 }
128 129
129 @AfterDestroy 130 @AfterDestroy
130 static decrementFollowerAndFollowingCount (instance: ActorFollowModel, options: any) { 131 static decrementFollowerAndFollowingCount (instance: ActorFollowModel, options: any) {
131 return Promise.all([ 132 return afterCommitIfTransaction(options.transaction, () => {
132 ActorModel.rebuildFollowsCount(instance.actorId, 'following', options.transaction), 133 return Promise.all([
133 ActorModel.rebuildFollowsCount(instance.targetActorId, 'followers', options.transaction) 134 ActorModel.rebuildFollowsCount(instance.actorId, 'following'),
134 ]) 135 ActorModel.rebuildFollowsCount(instance.targetActorId, 'followers')
136 ])
137 })
135 } 138 }
136 139
137 static removeFollowsOf (actorId: number, t?: Transaction) { 140 static removeFollowsOf (actorId: number, t?: Transaction) {
diff --git a/server/tests/api/server/auto-follows.ts b/server/tests/api/server/auto-follows.ts
index ce7b51925..ca6475bd5 100644
--- a/server/tests/api/server/auto-follows.ts
+++ b/server/tests/api/server/auto-follows.ts
@@ -19,16 +19,16 @@ async function checkFollow (follower: PeerTubeServer, following: PeerTubeServer,
19 const body = await following.follows.getFollowers({ start: 0, count: 5, sort: '-createdAt' }) 19 const body = await following.follows.getFollowers({ start: 0, count: 5, sort: '-createdAt' })
20 const follow = body.data.find(f => f.follower.host === follower.host && f.state === 'accepted') 20 const follow = body.data.find(f => f.follower.host === follower.host && f.state === 'accepted')
21 21
22 if (exists === true) expect(follow).to.exist 22 if (exists === true) expect(follow, `Follower ${follower.url} should exist on ${following.url}`).to.exist
23 else expect(follow).to.be.undefined 23 else expect(follow, `Follower ${follower.url} should not exist on ${following.url}`).to.be.undefined
24 } 24 }
25 25
26 { 26 {
27 const body = await follower.follows.getFollowings({ start: 0, count: 5, sort: '-createdAt' }) 27 const body = await follower.follows.getFollowings({ start: 0, count: 5, sort: '-createdAt' })
28 const follow = body.data.find(f => f.following.host === following.host && f.state === 'accepted') 28 const follow = body.data.find(f => f.following.host === following.host && f.state === 'accepted')
29 29
30 if (exists === true) expect(follow).to.exist 30 if (exists === true) expect(follow, `Following ${following.url} should exist on ${follower.url}`).to.exist
31 else expect(follow).to.be.undefined 31 else expect(follow, `Following ${following.url} should not exist on ${follower.url}`).to.be.undefined
32 } 32 }
33} 33}
34 34
diff --git a/server/tests/api/server/jobs.ts b/server/tests/api/server/jobs.ts
index 937028e4f..8c4e01226 100644
--- a/server/tests/api/server/jobs.ts
+++ b/server/tests/api/server/jobs.ts
@@ -88,8 +88,6 @@ describe('Test jobs', function () {
88 const jobs = body.data 88 const jobs = body.data
89 expect(jobs).to.have.length.above(2) 89 expect(jobs).to.have.length.above(2)
90 90
91 // We know there are a least 1 delayed job (video views) and 1 completed job (broadcast)
92 expect(jobs.find(j => j.state === 'delayed')).to.not.be.undefined
93 expect(jobs.find(j => j.state === 'completed')).to.not.be.undefined 91 expect(jobs.find(j => j.state === 'completed')).to.not.be.undefined
94 }) 92 })
95 93