aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models/redundancy
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2018-09-14 09:57:21 +0200
committerChocobozzz <me@florianbigard.com>2018-09-14 09:57:21 +0200
commitb36f41ca09e92ecb30d367d91d1089a23d10d585 (patch)
tree34b7c90e17f73f37d069a2f08d60dc36fa08372f /server/models/redundancy
parent6f0c46be8c9f4690d5e5cb758c4df6164b006f83 (diff)
downloadPeerTube-b36f41ca09e92ecb30d367d91d1089a23d10d585.tar.gz
PeerTube-b36f41ca09e92ecb30d367d91d1089a23d10d585.tar.zst
PeerTube-b36f41ca09e92ecb30d367d91d1089a23d10d585.zip
Add trending videos strategy
Diffstat (limited to 'server/models/redundancy')
-rw-r--r--server/models/redundancy/video-redundancy.ts115
1 files changed, 76 insertions, 39 deletions
diff --git a/server/models/redundancy/video-redundancy.ts b/server/models/redundancy/video-redundancy.ts
index 48ec77206..b13ade0f4 100644
--- a/server/models/redundancy/video-redundancy.ts
+++ b/server/models/redundancy/video-redundancy.ts
@@ -14,11 +14,10 @@ import {
14 UpdatedAt 14 UpdatedAt
15} from 'sequelize-typescript' 15} from 'sequelize-typescript'
16import { ActorModel } from '../activitypub/actor' 16import { ActorModel } from '../activitypub/actor'
17import { throwIfNotValid } from '../utils' 17import { getVideoSort, throwIfNotValid } from '../utils'
18import { isActivityPubUrlValid, isUrlValid } from '../../helpers/custom-validators/activitypub/misc' 18import { isActivityPubUrlValid, isUrlValid } from '../../helpers/custom-validators/activitypub/misc'
19import { CONSTRAINTS_FIELDS, VIDEO_EXT_MIMETYPE } from '../../initializers' 19import { CONFIG, CONSTRAINTS_FIELDS, VIDEO_EXT_MIMETYPE } from '../../initializers'
20import { VideoFileModel } from '../video/video-file' 20import { VideoFileModel } from '../video/video-file'
21import { isDateValid } from '../../helpers/custom-validators/misc'
22import { getServerActor } from '../../helpers/utils' 21import { getServerActor } from '../../helpers/utils'
23import { VideoModel } from '../video/video' 22import { VideoModel } from '../video/video'
24import { VideoRedundancyStrategy } from '../../../shared/models/redundancy' 23import { VideoRedundancyStrategy } from '../../../shared/models/redundancy'
@@ -145,50 +144,51 @@ export class VideoRedundancyModel extends Model<VideoRedundancyModel> {
145 return VideoRedundancyModel.findOne(query) 144 return VideoRedundancyModel.findOne(query)
146 } 145 }
147 146
147 static getVideoSample (rows: { id: number }[]) {
148 const ids = rows.map(r => r.id)
149 const id = sample(ids)
150
151 return VideoModel.loadWithFile(id, undefined, !isTestInstance())
152 }
153
148 static async findMostViewToDuplicate (randomizedFactor: number) { 154 static async findMostViewToDuplicate (randomizedFactor: number) {
149 // On VideoModel! 155 // On VideoModel!
150 const query = { 156 const query = {
157 attributes: [ 'id', 'views' ],
151 logging: !isTestInstance(), 158 logging: !isTestInstance(),
152 limit: randomizedFactor, 159 limit: randomizedFactor,
153 order: [ [ 'views', 'DESC' ] ], 160 order: getVideoSort('-views'),
154 include: [ 161 include: [
155 { 162 await VideoRedundancyModel.buildVideoFileForDuplication(),
156 model: VideoFileModel.unscoped(), 163 VideoRedundancyModel.buildServerRedundancyInclude()
157 required: true, 164 ]
158 where: { 165 }
159 id: { 166
160 [ Sequelize.Op.notIn ]: await VideoRedundancyModel.buildExcludeIn() 167 const rows = await VideoModel.unscoped().findAll(query)
161 } 168
162 } 169 return VideoRedundancyModel.getVideoSample(rows as { id: number }[])
163 }, 170 }
164 { 171
165 attributes: [], 172 static async findTrendingToDuplicate (randomizedFactor: number) {
166 model: VideoChannelModel.unscoped(), 173 // On VideoModel!
167 required: true, 174 const query = {
168 include: [ 175 attributes: [ 'id', 'views' ],
169 { 176 subQuery: false,
170 attributes: [], 177 logging: !isTestInstance(),
171 model: ActorModel.unscoped(), 178 group: 'VideoModel.id',
172 required: true, 179 limit: randomizedFactor,
173 include: [ 180 order: getVideoSort('-trending'),
174 { 181 include: [
175 attributes: [], 182 await VideoRedundancyModel.buildVideoFileForDuplication(),
176 model: ServerModel.unscoped(), 183 VideoRedundancyModel.buildServerRedundancyInclude(),
177 required: true, 184
178 where: { 185 VideoModel.buildTrendingQuery(CONFIG.TRENDING.VIDEOS.INTERVAL_DAYS)
179 redundancyAllowed: true
180 }
181 }
182 ]
183 }
184 ]
185 }
186 ] 186 ]
187 } 187 }
188 188
189 const rows = await VideoModel.unscoped().findAll(query) 189 const rows = await VideoModel.unscoped().findAll(query)
190 190
191 return sample(rows) 191 return VideoRedundancyModel.getVideoSample(rows as { id: number }[])
192 } 192 }
193 193
194 static async getVideoFiles (strategy: VideoRedundancyStrategy) { 194 static async getVideoFiles (strategy: VideoRedundancyStrategy) {
@@ -211,7 +211,7 @@ export class VideoRedundancyModel extends Model<VideoRedundancyModel> {
211 logging: !isTestInstance(), 211 logging: !isTestInstance(),
212 where: { 212 where: {
213 expiresOn: { 213 expiresOn: {
214 [Sequelize.Op.lt]: new Date() 214 [ Sequelize.Op.lt ]: new Date()
215 } 215 }
216 } 216 }
217 } 217 }
@@ -237,13 +237,50 @@ export class VideoRedundancyModel extends Model<VideoRedundancyModel> {
237 } 237 }
238 } 238 }
239 239
240 private static async buildExcludeIn () { 240 // Don't include video files we already duplicated
241 private static async buildVideoFileForDuplication () {
241 const actor = await getServerActor() 242 const actor = await getServerActor()
242 243
243 return Sequelize.literal( 244 const notIn = Sequelize.literal(
244 '(' + 245 '(' +
245 `SELECT "videoFileId" FROM "videoRedundancy" WHERE "actorId" = ${actor.id} AND "expiresOn" >= NOW()` + 246 `SELECT "videoFileId" FROM "videoRedundancy" WHERE "actorId" = ${actor.id} AND "expiresOn" >= NOW()` +
246 ')' 247 ')'
247 ) 248 )
249
250 return {
251 attributes: [],
252 model: VideoFileModel.unscoped(),
253 required: true,
254 where: {
255 id: {
256 [ Sequelize.Op.notIn ]: notIn
257 }
258 }
259 }
260 }
261
262 private static buildServerRedundancyInclude () {
263 return {
264 attributes: [],
265 model: VideoChannelModel.unscoped(),
266 required: true,
267 include: [
268 {
269 attributes: [],
270 model: ActorModel.unscoped(),
271 required: true,
272 include: [
273 {
274 attributes: [],
275 model: ServerModel.unscoped(),
276 required: true,
277 where: {
278 redundancyAllowed: true
279 }
280 }
281 ]
282 }
283 ]
284 }
248 } 285 }
249} 286}