mirror of https://github.com/Chocobozzz/PeerTube
Avoid too many requests and fetching outbox
parent
f05a1c30c1
commit
54e740594b
|
@ -4,9 +4,11 @@ import { activityPubCollectionPagination } from '../../helpers/activitypub'
|
|||
import { pageToStartAndCount } from '../../helpers/core-utils'
|
||||
import { ACTIVITY_PUB } from '../../initializers/constants'
|
||||
import { announceActivityData, createActivityData } from '../../lib/activitypub/send'
|
||||
import { buildAudience } from '../../lib/activitypub/send/misc'
|
||||
import { getAnnounceActivityPubUrl } from '../../lib/activitypub/url'
|
||||
import { asyncMiddleware, localAccountValidator } from '../../middlewares'
|
||||
import { AccountModel } from '../../models/account/account'
|
||||
import { ActorModel } from '../../models/activitypub/actor'
|
||||
import { VideoModel } from '../../models/video/video'
|
||||
|
||||
const outboxRouter = express.Router()
|
||||
|
@ -34,20 +36,29 @@ async function outboxController (req: express.Request, res: express.Response, ne
|
|||
const data = await VideoModel.listAllAndSharedByActorForOutbox(actor.id, start, count)
|
||||
const activities: Activity[] = []
|
||||
|
||||
// Avoid too many SQL requests
|
||||
const actors = data.data.map(v => v.VideoChannel.Account.Actor)
|
||||
actors.push(actor)
|
||||
|
||||
const followersMatrix = await ActorModel.getActorsFollowerSharedInboxUrls(actors, undefined)
|
||||
|
||||
for (const video of data.data) {
|
||||
const videoObject = video.toActivityPubObject()
|
||||
|
||||
const videoChannel = video.VideoChannel
|
||||
const byActor = video.VideoChannel.Account.Actor
|
||||
const createActivityAudience = buildAudience(followersMatrix[byActor.id])
|
||||
|
||||
// This is a shared video
|
||||
if (video.VideoShares !== undefined && video.VideoShares.length !== 0) {
|
||||
const createActivity = await createActivityData(video.url, videoChannel.Account.Actor, videoObject, undefined)
|
||||
const createActivity = await createActivityData(video.url, byActor, videoObject, undefined, createActivityAudience)
|
||||
|
||||
const announceAudience = buildAudience(followersMatrix[actor.id])
|
||||
const url = getAnnounceActivityPubUrl(video.url, actor)
|
||||
const announceActivity = await announceActivityData(url, actor, createActivity, undefined)
|
||||
const announceActivity = await announceActivityData(url, actor, createActivity, undefined, announceAudience)
|
||||
|
||||
activities.push(announceActivity)
|
||||
} else {
|
||||
const createActivity = await createActivityData(video.url, videoChannel.Account.Actor, videoObject, undefined)
|
||||
const createActivity = await createActivityData(video.url, byActor, videoObject, undefined, createActivityAudience)
|
||||
|
||||
activities.push(createActivity)
|
||||
}
|
||||
|
|
|
@ -143,6 +143,10 @@ async function getActorsInvolvedInVideo (video: VideoModel, t: Transaction) {
|
|||
async function getAudience (actorSender: ActorModel, t: Transaction, isPublic = true) {
|
||||
const followerInboxUrls = await actorSender.getFollowerSharedInboxUrls(t)
|
||||
|
||||
return buildAudience(followerInboxUrls, isPublic)
|
||||
}
|
||||
|
||||
function buildAudience (followerInboxUrls: string[], isPublic = true) {
|
||||
// Thanks Mastodon: https://github.com/tootsuite/mastodon/blob/master/app/lib/activitypub/tag_manager.rb#L47
|
||||
let to = []
|
||||
let cc = []
|
||||
|
@ -183,6 +187,7 @@ async function computeUris (toActors: ActorModel[], actorsException: ActorModel[
|
|||
export {
|
||||
broadcastToFollowers,
|
||||
unicastTo,
|
||||
buildAudience,
|
||||
getAudience,
|
||||
getOriginVideoAudience,
|
||||
getActorsInvolvedInVideo,
|
||||
|
|
|
@ -375,7 +375,8 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
|
|||
score: {
|
||||
[Sequelize.Op.lte]: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
logger: false
|
||||
}
|
||||
|
||||
return ActorFollowModel.findAll(query)
|
||||
|
|
|
@ -167,17 +167,17 @@ export class ActorModel extends Model<ActorModel> {
|
|||
},
|
||||
onDelete: 'cascade'
|
||||
})
|
||||
AccountFollowing: ActorFollowModel[]
|
||||
ActorFollowing: ActorFollowModel[]
|
||||
|
||||
@HasMany(() => ActorFollowModel, {
|
||||
foreignKey: {
|
||||
name: 'targetActorId',
|
||||
allowNull: false
|
||||
},
|
||||
as: 'followers',
|
||||
as: 'ActorFollowers',
|
||||
onDelete: 'cascade'
|
||||
})
|
||||
AccountFollowers: ActorFollowModel[]
|
||||
ActorFollowers: ActorFollowModel[]
|
||||
|
||||
@ForeignKey(() => ServerModel)
|
||||
@Column
|
||||
|
@ -277,6 +277,45 @@ export class ActorModel extends Model<ActorModel> {
|
|||
})
|
||||
}
|
||||
|
||||
static async getActorsFollowerSharedInboxUrls (actors: ActorModel[], t: Sequelize.Transaction) {
|
||||
const query = {
|
||||
// attribute: [],
|
||||
where: {
|
||||
id: {
|
||||
[Sequelize.Op.in]: actors.map(a => a.id)
|
||||
}
|
||||
},
|
||||
include: [
|
||||
{
|
||||
// attributes: [ ],
|
||||
model: ActorFollowModel.unscoped(),
|
||||
required: true,
|
||||
as: 'ActorFollowers',
|
||||
where: {
|
||||
state: 'accepted'
|
||||
},
|
||||
include: [
|
||||
{
|
||||
attributes: [ 'sharedInboxUrl' ],
|
||||
model: ActorModel.unscoped(),
|
||||
as: 'ActorFollower',
|
||||
required: true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
transaction: t
|
||||
}
|
||||
|
||||
const hash: { [ id: number ]: string[] } = {}
|
||||
const res = await ActorModel.findAll(query)
|
||||
for (const actor of res) {
|
||||
hash[actor.id] = actor.ActorFollowers.map(follow => follow.ActorFollower.sharedInboxUrl)
|
||||
}
|
||||
|
||||
return hash
|
||||
}
|
||||
|
||||
toFormattedJSON () {
|
||||
let avatar: Avatar = null
|
||||
if (this.Avatar) {
|
||||
|
@ -347,10 +386,12 @@ export class ActorModel extends Model<ActorModel> {
|
|||
attributes: [ 'sharedInboxUrl' ],
|
||||
include: [
|
||||
{
|
||||
model: ActorFollowModel,
|
||||
attribute: [],
|
||||
model: ActorFollowModel.unscoped(),
|
||||
required: true,
|
||||
as: 'followers',
|
||||
as: 'ActorFollowers',
|
||||
where: {
|
||||
state: 'accepted',
|
||||
targetActorId: this.id
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ enum ScopeNames {
|
|||
'$VideoChannel.Account.Actor.serverId$': null
|
||||
},
|
||||
{
|
||||
'$VideoChannel.Account.Actor.followers.actorId$': actorId
|
||||
'$VideoChannel.Account.Actor.ActorFollowers.actorId$': actorId
|
||||
},
|
||||
{
|
||||
id: {
|
||||
|
@ -106,7 +106,7 @@ enum ScopeNames {
|
|||
{
|
||||
attributes: [ ],
|
||||
model: ActorFollowModel.unscoped(),
|
||||
as: 'followers',
|
||||
as: 'ActorFollowers',
|
||||
required: false
|
||||
}
|
||||
]
|
||||
|
|
|
@ -4,7 +4,7 @@ import * as chai from 'chai'
|
|||
import 'mocha'
|
||||
import { Video, VideoPrivacy } from '../../../../shared/models/videos'
|
||||
import { VideoComment, VideoCommentThreadTree } from '../../../../shared/models/videos/video-comment.model'
|
||||
import { checkVideoFilesWereRemoved, completeVideoCheck, getVideoChannelsList } from '../../utils'
|
||||
import { checkVideoFilesWereRemoved, completeVideoCheck } from '../../utils'
|
||||
|
||||
import {
|
||||
flushAndRunMultipleServers, flushTests, getVideosList, killallServers, ServerInfo, setAccessTokensToServers, uploadVideo,
|
||||
|
@ -12,7 +12,7 @@ import {
|
|||
} from '../../utils/index'
|
||||
import { dateIsValid } from '../../utils/miscs/miscs'
|
||||
import { follow, getFollowersListPaginationAndSort, getFollowingListPaginationAndSort, unfollow } from '../../utils/server/follows'
|
||||
import { expectAccountFollows, getAccountsList } from '../../utils/users/accounts'
|
||||
import { expectAccountFollows } from '../../utils/users/accounts'
|
||||
import { userLogin } from '../../utils/users/login'
|
||||
import { createUser } from '../../utils/users/users'
|
||||
import {
|
||||
|
@ -354,12 +354,6 @@ describe('Test follows', function () {
|
|||
let res = await getVideosList(servers[ 0 ].url)
|
||||
expect(res.body.total).to.equal(1)
|
||||
|
||||
res = await getVideoChannelsList(servers[0].url, 0, 1)
|
||||
expect(res.body.total).to.equal(2)
|
||||
|
||||
res = await getAccountsList(servers[0].url)
|
||||
expect(res.body.total).to.equal(2)
|
||||
|
||||
await checkVideoFilesWereRemoved(video4.uuid, servers[0].serverNumber)
|
||||
})
|
||||
|
||||
|
|
Loading…
Reference in New Issue