aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2018-09-24 13:07:33 +0200
committerChocobozzz <me@florianbigard.com>2018-09-24 13:38:39 +0200
commite5565833f62b97f62ea75eba5b479963ae78b873 (patch)
tree835793ce464f9666b0ceae79f3d278cc4e007b32 /server/models
parentd1a63fc7ac58a1db00d8ca4f43aadba02eb9b084 (diff)
downloadPeerTube-e5565833f62b97f62ea75eba5b479963ae78b873.tar.gz
PeerTube-e5565833f62b97f62ea75eba5b479963ae78b873.tar.zst
PeerTube-e5565833f62b97f62ea75eba5b479963ae78b873.zip
Improve redundancy: add 'min_lifetime' configuration
Diffstat (limited to 'server/models')
-rw-r--r--server/models/activitypub/actor.ts31
-rw-r--r--server/models/redundancy/video-redundancy.ts64
-rw-r--r--server/models/video/video-file.ts6
3 files changed, 86 insertions, 15 deletions
diff --git a/server/models/activitypub/actor.ts b/server/models/activitypub/actor.ts
index f8bb59323..12b83916e 100644
--- a/server/models/activitypub/actor.ts
+++ b/server/models/activitypub/actor.ts
@@ -37,6 +37,7 @@ import { ServerModel } from '../server/server'
37import { throwIfNotValid } from '../utils' 37import { throwIfNotValid } from '../utils'
38import { VideoChannelModel } from '../video/video-channel' 38import { VideoChannelModel } from '../video/video-channel'
39import { ActorFollowModel } from './actor-follow' 39import { ActorFollowModel } from './actor-follow'
40import { VideoModel } from '../video/video'
40 41
41enum ScopeNames { 42enum ScopeNames {
42 FULL = 'FULL' 43 FULL = 'FULL'
@@ -266,6 +267,36 @@ export class ActorModel extends Model<ActorModel> {
266 return ActorModel.unscoped().findById(id) 267 return ActorModel.unscoped().findById(id)
267 } 268 }
268 269
270 static loadAccountActorByVideoId (videoId: number, transaction: Sequelize.Transaction) {
271 const query = {
272 include: [
273 {
274 attributes: [ 'id' ],
275 model: AccountModel.unscoped(),
276 required: true,
277 include: [
278 {
279 attributes: [ 'id' ],
280 model: VideoChannelModel.unscoped(),
281 required: true,
282 include: {
283 attributes: [ 'id' ],
284 model: VideoModel.unscoped(),
285 required: true,
286 where: {
287 id: videoId
288 }
289 }
290 }
291 ]
292 }
293 ],
294 transaction
295 }
296
297 return ActorModel.unscoped().findOne(query as any) // FIXME: typings
298 }
299
269 static isActorUrlExist (url: string) { 300 static isActorUrlExist (url: string) {
270 const query = { 301 const query = {
271 raw: true, 302 raw: true,
diff --git a/server/models/redundancy/video-redundancy.ts b/server/models/redundancy/video-redundancy.ts
index fb07287a8..970d2fe06 100644
--- a/server/models/redundancy/video-redundancy.ts
+++ b/server/models/redundancy/video-redundancy.ts
@@ -9,7 +9,6 @@ import {
9 Is, 9 Is,
10 Model, 10 Model,
11 Scopes, 11 Scopes,
12 Sequelize,
13 Table, 12 Table,
14 UpdatedAt 13 UpdatedAt
15} from 'sequelize-typescript' 14} from 'sequelize-typescript'
@@ -28,6 +27,7 @@ import { ServerModel } from '../server/server'
28import { sample } from 'lodash' 27import { sample } from 'lodash'
29import { isTestInstance } from '../../helpers/core-utils' 28import { isTestInstance } from '../../helpers/core-utils'
30import * as Bluebird from 'bluebird' 29import * as Bluebird from 'bluebird'
30import * as Sequelize from 'sequelize'
31 31
32export enum ScopeNames { 32export enum ScopeNames {
33 WITH_VIDEO = 'WITH_VIDEO' 33 WITH_VIDEO = 'WITH_VIDEO'
@@ -116,11 +116,11 @@ export class VideoRedundancyModel extends Model<VideoRedundancyModel> {
116 Actor: ActorModel 116 Actor: ActorModel
117 117
118 @AfterDestroy 118 @AfterDestroy
119 static removeFilesAndSendDelete (instance: VideoRedundancyModel) { 119 static removeFile (instance: VideoRedundancyModel) {
120 // Not us 120 // Not us
121 if (!instance.strategy) return 121 if (!instance.strategy) return
122 122
123 logger.info('Removing video file %s-.', instance.VideoFile.Video.uuid, instance.VideoFile.resolution) 123 logger.info('Removing duplicated video file %s-%s.', instance.VideoFile.Video.uuid, instance.VideoFile.resolution)
124 124
125 return instance.VideoFile.Video.removeFile(instance.VideoFile) 125 return instance.VideoFile.Video.removeFile(instance.VideoFile)
126 } 126 }
@@ -135,11 +135,12 @@ export class VideoRedundancyModel extends Model<VideoRedundancyModel> {
135 return VideoRedundancyModel.scope(ScopeNames.WITH_VIDEO).findOne(query) 135 return VideoRedundancyModel.scope(ScopeNames.WITH_VIDEO).findOne(query)
136 } 136 }
137 137
138 static loadByUrl (url: string) { 138 static loadByUrl (url: string, transaction?: Sequelize.Transaction) {
139 const query = { 139 const query = {
140 where: { 140 where: {
141 url 141 url
142 } 142 },
143 transaction
143 } 144 }
144 145
145 return VideoRedundancyModel.findOne(query) 146 return VideoRedundancyModel.findOne(query)
@@ -157,7 +158,6 @@ export class VideoRedundancyModel extends Model<VideoRedundancyModel> {
157 // On VideoModel! 158 // On VideoModel!
158 const query = { 159 const query = {
159 attributes: [ 'id', 'views' ], 160 attributes: [ 'id', 'views' ],
160 logging: !isTestInstance(),
161 limit: randomizedFactor, 161 limit: randomizedFactor,
162 order: getVideoSort('-views'), 162 order: getVideoSort('-views'),
163 include: [ 163 include: [
@@ -174,7 +174,6 @@ export class VideoRedundancyModel extends Model<VideoRedundancyModel> {
174 const query = { 174 const query = {
175 attributes: [ 'id', 'views' ], 175 attributes: [ 'id', 'views' ],
176 subQuery: false, 176 subQuery: false,
177 logging: !isTestInstance(),
178 group: 'VideoModel.id', 177 group: 'VideoModel.id',
179 limit: randomizedFactor, 178 limit: randomizedFactor,
180 order: getVideoSort('-trending'), 179 order: getVideoSort('-trending'),
@@ -193,7 +192,6 @@ export class VideoRedundancyModel extends Model<VideoRedundancyModel> {
193 // On VideoModel! 192 // On VideoModel!
194 const query = { 193 const query = {
195 attributes: [ 'id', 'publishedAt' ], 194 attributes: [ 'id', 'publishedAt' ],
196 logging: !isTestInstance(),
197 limit: randomizedFactor, 195 limit: randomizedFactor,
198 order: getVideoSort('-publishedAt'), 196 order: getVideoSort('-publishedAt'),
199 where: { 197 where: {
@@ -210,11 +208,29 @@ export class VideoRedundancyModel extends Model<VideoRedundancyModel> {
210 return VideoRedundancyModel.getVideoSample(VideoModel.unscoped().findAll(query)) 208 return VideoRedundancyModel.getVideoSample(VideoModel.unscoped().findAll(query))
211 } 209 }
212 210
211 static async loadOldestLocalThatAlreadyExpired (strategy: VideoRedundancyStrategy, expiresAfterMs: number) {
212 const expiredDate = new Date()
213 expiredDate.setMilliseconds(expiredDate.getMilliseconds() - expiresAfterMs)
214
215 const actor = await getServerActor()
216
217 const query = {
218 where: {
219 actorId: actor.id,
220 strategy,
221 createdAt: {
222 [ Sequelize.Op.lt ]: expiredDate
223 }
224 }
225 }
226
227 return VideoRedundancyModel.scope([ ScopeNames.WITH_VIDEO ]).findOne(query)
228 }
229
213 static async getTotalDuplicated (strategy: VideoRedundancyStrategy) { 230 static async getTotalDuplicated (strategy: VideoRedundancyStrategy) {
214 const actor = await getServerActor() 231 const actor = await getServerActor()
215 232
216 const options = { 233 const options = {
217 logging: !isTestInstance(),
218 include: [ 234 include: [
219 { 235 {
220 attributes: [], 236 attributes: [],
@@ -228,21 +244,39 @@ export class VideoRedundancyModel extends Model<VideoRedundancyModel> {
228 ] 244 ]
229 } 245 }
230 246
231 return VideoFileModel.sum('size', options) 247 return VideoFileModel.sum('size', options as any) // FIXME: typings
232 } 248 }
233 249
234 static listAllExpired () { 250 static async listLocalExpired () {
251 const actor = await getServerActor()
252
253 const query = {
254 where: {
255 actorId: actor.id,
256 expiresOn: {
257 [ Sequelize.Op.lt ]: new Date()
258 }
259 }
260 }
261
262 return VideoRedundancyModel.scope([ ScopeNames.WITH_VIDEO ]).findAll(query)
263 }
264
265 static async listRemoteExpired () {
266 const actor = await getServerActor()
267
235 const query = { 268 const query = {
236 logging: !isTestInstance(),
237 where: { 269 where: {
270 actorId: {
271 [Sequelize.Op.ne]: actor.id
272 },
238 expiresOn: { 273 expiresOn: {
239 [ Sequelize.Op.lt ]: new Date() 274 [ Sequelize.Op.lt ]: new Date()
240 } 275 }
241 } 276 }
242 } 277 }
243 278
244 return VideoRedundancyModel.scope(ScopeNames.WITH_VIDEO) 279 return VideoRedundancyModel.scope([ ScopeNames.WITH_VIDEO ]).findAll(query)
245 .findAll(query)
246 } 280 }
247 281
248 static async getStats (strategy: VideoRedundancyStrategy) { 282 static async getStats (strategy: VideoRedundancyStrategy) {
@@ -299,7 +333,7 @@ export class VideoRedundancyModel extends Model<VideoRedundancyModel> {
299 333
300 const notIn = Sequelize.literal( 334 const notIn = Sequelize.literal(
301 '(' + 335 '(' +
302 `SELECT "videoFileId" FROM "videoRedundancy" WHERE "actorId" = ${actor.id} AND "expiresOn" >= NOW()` + 336 `SELECT "videoFileId" FROM "videoRedundancy" WHERE "actorId" = ${actor.id}` +
303 ')' 337 ')'
304 ) 338 )
305 339
diff --git a/server/models/video/video-file.ts b/server/models/video/video-file.ts
index 0907ea569..0887a3738 100644
--- a/server/models/video/video-file.ts
+++ b/server/models/video/video-file.ts
@@ -106,4 +106,10 @@ export class VideoFileModel extends Model<VideoFileModel> {
106 return results.length === 1 106 return results.length === 1
107 }) 107 })
108 } 108 }
109
110 hasSameUniqueKeysThan (other: VideoFileModel) {
111 return this.fps === other.fps &&
112 this.resolution === other.resolution &&
113 this.videoId === other.videoId
114 }
109} 115}