From e1ab52d7ec7370a6f9f5937192d6003206af1ac0 Mon Sep 17 00:00:00 2001 From: kontrollanten <6680299+kontrollanten@users.noreply.github.com> Date: Tue, 9 Nov 2021 11:05:35 +0100 Subject: Add migrate-to-object-storage script (#4481) * add migrate-to-object-storage-script closes #4467 * add migrate-to-unique-playlist-filenames script * fix(migrate-to-unique-playlist-filenames): update master/segments256 run updateMasterHLSPlaylist and updateSha256VODSegments after file rename. * Improve move to object storage scripts * PR remarks Co-authored-by: Chocobozzz --- server/lib/hls.ts | 6 +++--- server/lib/job-queue/job-queue.ts | 8 +++++++- server/lib/video-state.ts | 38 +++++++++++++++++++++++--------------- 3 files changed, 33 insertions(+), 19 deletions(-) (limited to 'server/lib') diff --git a/server/lib/hls.ts b/server/lib/hls.ts index 0828a2d0f..8160e7949 100644 --- a/server/lib/hls.ts +++ b/server/lib/hls.ts @@ -1,7 +1,7 @@ import { close, ensureDir, move, open, outputJSON, read, readFile, remove, stat, writeFile } from 'fs-extra' import { flatten, uniq } from 'lodash' import { basename, dirname, join } from 'path' -import { MStreamingPlaylistFilesVideo, MVideoWithFile } from '@server/types/models' +import { MStreamingPlaylistFilesVideo, MVideo, MVideoUUID } from '@server/types/models' import { sha256 } from '../helpers/core-utils' import { getAudioStreamCodec, getVideoStreamCodec, getVideoStreamSize } from '../helpers/ffprobe-utils' import { logger } from '../helpers/logger' @@ -31,7 +31,7 @@ async function updateStreamingPlaylistsInfohashesIfNeeded () { } } -async function updateMasterHLSPlaylist (video: MVideoWithFile, playlist: MStreamingPlaylistFilesVideo) { +async function updateMasterHLSPlaylist (video: MVideo, playlist: MStreamingPlaylistFilesVideo) { const masterPlaylists: string[] = [ '#EXTM3U', '#EXT-X-VERSION:3' ] for (const file of playlist.VideoFiles) { @@ -63,7 +63,7 @@ async function updateMasterHLSPlaylist (video: MVideoWithFile, playlist: MStream }) } -async function updateSha256VODSegments (video: MVideoWithFile, playlist: MStreamingPlaylistFilesVideo) { +async function updateSha256VODSegments (video: MVideoUUID, playlist: MStreamingPlaylistFilesVideo) { const json: { [filename: string]: { [range: string]: string } } = {} // For all the resolutions available for this video diff --git a/server/lib/job-queue/job-queue.ts b/server/lib/job-queue/job-queue.ts index 53d6b6a9c..0eab720d9 100644 --- a/server/lib/job-queue/job-queue.ts +++ b/server/lib/job-queue/job-queue.ts @@ -108,7 +108,7 @@ class JobQueue { private constructor () { } - init () { + init (produceOnly = false) { // Already initialized if (this.initialized === true) return this.initialized = true @@ -124,6 +124,12 @@ class JobQueue { for (const handlerName of (Object.keys(handlers) as JobType[])) { const queue = new Bull(handlerName, queueOptions) + + if (produceOnly) { + queue.pause(true) + .catch(err => logger.error('Cannot pause queue %s in produced only job queue', handlerName, { err })) + } + const handler = handlers[handlerName] queue.process(this.getJobConcurrency(handlerName), handler) diff --git a/server/lib/video-state.ts b/server/lib/video-state.ts index 9352a67d1..d5bbbec43 100644 --- a/server/lib/video-state.ts +++ b/server/lib/video-state.ts @@ -57,10 +57,33 @@ function moveToNextState (video: MVideoUUID, isNewVideo = true) { }) } +async function moveToExternalStorageState (video: MVideoFullLight, isNewVideo: boolean, transaction: Transaction) { + const videoJobInfo = await VideoJobInfoModel.load(video.id, transaction) + const pendingTranscode = videoJobInfo?.pendingTranscode || 0 + + // We want to wait all transcoding jobs before moving the video on an external storage + if (pendingTranscode !== 0) return false + + await video.setNewState(VideoState.TO_MOVE_TO_EXTERNAL_STORAGE, isNewVideo, transaction) + + logger.info('Creating external storage move job for video %s.', video.uuid, { tags: [ video.uuid ] }) + + try { + await addMoveToObjectStorageJob(video, isNewVideo) + + return true + } catch (err) { + logger.error('Cannot add move to object storage job', { err }) + + return false + } +} + // --------------------------------------------------------------------------- export { buildNextVideoState, + moveToExternalStorageState, moveToNextState } @@ -82,18 +105,3 @@ async function moveToPublishedState (video: MVideoFullLight, isNewVideo: boolean Notifier.Instance.notifyOnVideoPublishedAfterTranscoding(video) } } - -async function moveToExternalStorageState (video: MVideoFullLight, isNewVideo: boolean, transaction: Transaction) { - const videoJobInfo = await VideoJobInfoModel.load(video.id, transaction) - const pendingTranscode = videoJobInfo?.pendingTranscode || 0 - - // We want to wait all transcoding jobs before moving the video on an external storage - if (pendingTranscode !== 0) return - - await video.setNewState(VideoState.TO_MOVE_TO_EXTERNAL_STORAGE, isNewVideo, transaction) - - logger.info('Creating external storage move job for video %s.', video.uuid, { tags: [ video.uuid ] }) - - addMoveToObjectStorageJob(video, isNewVideo) - .catch(err => logger.error('Cannot add move to object storage job', { err })) -} -- cgit v1.2.3