X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Flib%2Fschedulers%2Fvideos-redundancy-scheduler.ts;h=c1c91b6563d9488ca1b37d8ea2cce68fc544d119;hb=66fb2aa39b6f8e4677f80128c27fbafd3a8fe2e7;hp=04f601bfb9266f8cd2ec693c38d813e75495737f;hpb=0b353d1d8a659140d10b8f7bff3f114698c1a715;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/lib/schedulers/videos-redundancy-scheduler.ts b/server/lib/schedulers/videos-redundancy-scheduler.ts index 04f601bfb..c1c91b656 100644 --- a/server/lib/schedulers/videos-redundancy-scheduler.ts +++ b/server/lib/schedulers/videos-redundancy-scheduler.ts @@ -3,8 +3,7 @@ import { HLS_REDUNDANCY_DIRECTORY, REDUNDANCY, VIDEO_IMPORT_TIMEOUT, WEBSERVER } import { logger } from '../../helpers/logger' import { VideosRedundancy } from '../../../shared/models/redundancy' import { VideoRedundancyModel } from '../../models/redundancy/video-redundancy' -import { VideoFileModel } from '../../models/video/video-file' -import { downloadWebTorrentVideo } from '../../helpers/webtorrent' +import { downloadWebTorrentVideo, generateMagnetUri } from '../../helpers/webtorrent' import { join } from 'path' import { move } from 'fs-extra' import { getServerActor } from '../../helpers/utils' @@ -12,16 +11,32 @@ import { sendCreateCacheFile, sendUpdateCacheFile } from '../activitypub/send' import { getVideoCacheFileActivityPubUrl, getVideoCacheStreamingPlaylistActivityPubUrl } from '../activitypub/url' import { removeVideoRedundancy } from '../redundancy' import { getOrCreateVideoAndAccountAndChannel } from '../activitypub' -import { VideoStreamingPlaylistModel } from '../../models/video/video-streaming-playlist' -import { VideoModel } from '../../models/video/video' import { downloadPlaylistSegments } from '../hls' import { CONFIG } from '../../initializers/config' +import { + MStreamingPlaylist, MStreamingPlaylistFiles, + MStreamingPlaylistVideo, + MVideoAccountLight, + MVideoFile, + MVideoFileVideo, + MVideoRedundancyFileVideo, + MVideoRedundancyStreamingPlaylistVideo, + MVideoRedundancyVideo, + MVideoWithAllFiles +} from '@server/typings/models' +import { getVideoFilename } from '../video-paths' type CandidateToDuplicate = { redundancy: VideosRedundancy, - video: VideoModel, - files: VideoFileModel[], - streamingPlaylists: VideoStreamingPlaylistModel[] + video: MVideoWithAllFiles, + files: MVideoFile[], + streamingPlaylists: MStreamingPlaylistFiles[] +} + +function isMVideoRedundancyFileVideo ( + o: MVideoRedundancyFileVideo | MVideoRedundancyStreamingPlaylistVideo +): o is MVideoRedundancyFileVideo { + return !!(o as MVideoRedundancyFileVideo).VideoFile } export class VideosRedundancyScheduler extends AbstractScheduler { @@ -102,7 +117,7 @@ export class VideosRedundancyScheduler extends AbstractScheduler { } } - private async extendsRedundancy (redundancyModel: VideoRedundancyModel) { + private async extendsRedundancy (redundancyModel: MVideoRedundancyVideo) { const redundancy = CONFIG.REDUNDANCY.VIDEOS.STRATEGIES.find(s => s.strategy === redundancyModel.strategy) // Redundancy strategy disabled, remove our redundancy instead of extending expiration if (!redundancy) { @@ -172,7 +187,8 @@ export class VideosRedundancyScheduler extends AbstractScheduler { } } - private async createVideoFileRedundancy (redundancy: VideosRedundancy, video: VideoModel, file: VideoFileModel) { + private async createVideoFileRedundancy (redundancy: VideosRedundancy, video: MVideoAccountLight, fileArg: MVideoFile) { + const file = fileArg as MVideoFileVideo file.Video = video const serverActor = await getServerActor() @@ -180,14 +196,14 @@ export class VideosRedundancyScheduler extends AbstractScheduler { logger.info('Duplicating %s - %d in videos redundancy with "%s" strategy.', video.url, file.resolution, redundancy.strategy) const { baseUrlHttp, baseUrlWs } = video.getBaseUrls() - const magnetUri = video.generateMagnetUri(file, baseUrlHttp, baseUrlWs) + const magnetUri = generateMagnetUri(video, file, baseUrlHttp, baseUrlWs) const tmpPath = await downloadWebTorrentVideo({ magnetUri }, VIDEO_IMPORT_TIMEOUT) - const destPath = join(CONFIG.STORAGE.REDUNDANCY_DIR, video.getVideoFilename(file)) - await move(tmpPath, destPath) + const destPath = join(CONFIG.STORAGE.REDUNDANCY_DIR, getVideoFilename(video, file)) + await move(tmpPath, destPath, { overwrite: true }) - const createdModel = await VideoRedundancyModel.create({ + const createdModel: MVideoRedundancyFileVideo = await VideoRedundancyModel.create({ expiresOn: this.buildNewExpiration(redundancy.minLifetime), url: getVideoCacheFileActivityPubUrl(file), fileUrl: video.getVideoRedundancyUrl(file, WEBSERVER.URL), @@ -203,7 +219,12 @@ export class VideosRedundancyScheduler extends AbstractScheduler { logger.info('Duplicated %s - %d -> %s.', video.url, file.resolution, createdModel.url) } - private async createStreamingPlaylistRedundancy (redundancy: VideosRedundancy, video: VideoModel, playlist: VideoStreamingPlaylistModel) { + private async createStreamingPlaylistRedundancy ( + redundancy: VideosRedundancy, + video: MVideoAccountLight, + playlistArg: MStreamingPlaylist + ) { + const playlist = playlistArg as MStreamingPlaylistVideo playlist.Video = video const serverActor = await getServerActor() @@ -213,7 +234,7 @@ export class VideosRedundancyScheduler extends AbstractScheduler { const destDirectory = join(HLS_REDUNDANCY_DIRECTORY, video.uuid) await downloadPlaylistSegments(playlist.playlistUrl, destDirectory, VIDEO_IMPORT_TIMEOUT) - const createdModel = await VideoRedundancyModel.create({ + const createdModel: MVideoRedundancyStreamingPlaylistVideo = await VideoRedundancyModel.create({ expiresOn: this.buildNewExpiration(redundancy.minLifetime), url: getVideoCacheStreamingPlaylistActivityPubUrl(video, playlist), fileUrl: playlist.getVideoRedundancyUrl(WEBSERVER.URL), @@ -229,7 +250,7 @@ export class VideosRedundancyScheduler extends AbstractScheduler { logger.info('Duplicated playlist %s -> %s.', playlist.playlistUrl, createdModel.url) } - private async extendsExpirationOf (redundancy: VideoRedundancyModel, expiresAfterMs: number) { + private async extendsExpirationOf (redundancy: MVideoRedundancyVideo, expiresAfterMs: number) { logger.info('Extending expiration of %s.', redundancy.url) const serverActor = await getServerActor() @@ -241,9 +262,9 @@ export class VideosRedundancyScheduler extends AbstractScheduler { } private async purgeCacheIfNeeded (candidateToDuplicate: CandidateToDuplicate) { - while (this.isTooHeavy(candidateToDuplicate)) { + while (await this.isTooHeavy(candidateToDuplicate)) { const redundancy = candidateToDuplicate.redundancy - const toDelete = await VideoRedundancyModel.loadOldestLocalThatAlreadyExpired(redundancy.strategy, redundancy.minLifetime) + const toDelete = await VideoRedundancyModel.loadOldestLocalExpired(redundancy.strategy, redundancy.minLifetime) if (!toDelete) return await removeVideoRedundancy(toDelete) @@ -263,19 +284,21 @@ export class VideosRedundancyScheduler extends AbstractScheduler { return new Date(Date.now() + expiresAfterMs) } - private buildEntryLogId (object: VideoRedundancyModel) { - if (object.VideoFile) return `${object.VideoFile.Video.url}-${object.VideoFile.resolution}` + private buildEntryLogId (object: MVideoRedundancyFileVideo | MVideoRedundancyStreamingPlaylistVideo) { + if (isMVideoRedundancyFileVideo(object)) return `${object.VideoFile.Video.url}-${object.VideoFile.resolution}` return `${object.VideoStreamingPlaylist.playlistUrl}` } - private getTotalFileSizes (files: VideoFileModel[], playlists: VideoStreamingPlaylistModel[]) { - const fileReducer = (previous: number, current: VideoFileModel) => previous + current.size + private getTotalFileSizes (files: MVideoFile[], playlists: MStreamingPlaylistFiles[]) { + const fileReducer = (previous: number, current: MVideoFile) => previous + current.size - const totalSize = files.reduce(fileReducer, 0) - if (playlists.length === 0) return totalSize + let allFiles = files + for (const p of playlists) { + allFiles = allFiles.concat(p.VideoFiles) + } - return totalSize * playlists.length + return allFiles.reduce(fileReducer, 0) } private async loadAndRefreshVideo (videoUrl: string) {