Painfully debug concurrent import jobs
This commit is contained in:
parent
80428d16a0
commit
44d1f7f2e8
|
@ -1,11 +1,13 @@
|
||||||
import * as Bull from 'bull'
|
import * as Bull from 'bull'
|
||||||
import { move, remove, stat } from 'fs-extra'
|
import { move, remove, stat } from 'fs-extra'
|
||||||
import { extname } from 'path'
|
import { extname } from 'path'
|
||||||
|
import { retryTransactionWrapper } from '@server/helpers/database-utils'
|
||||||
import { isPostImportVideoAccepted } from '@server/lib/moderation'
|
import { isPostImportVideoAccepted } from '@server/lib/moderation'
|
||||||
import { Hooks } from '@server/lib/plugins/hooks'
|
import { Hooks } from '@server/lib/plugins/hooks'
|
||||||
import { isAbleToUploadVideo } from '@server/lib/user'
|
import { isAbleToUploadVideo } from '@server/lib/user'
|
||||||
import { addOptimizeOrMergeAudioJob } from '@server/lib/video'
|
import { addOptimizeOrMergeAudioJob } from '@server/lib/video'
|
||||||
import { getVideoFilePath } from '@server/lib/video-paths'
|
import { getVideoFilePath } from '@server/lib/video-paths'
|
||||||
|
import { ThumbnailModel } from '@server/models/video/thumbnail'
|
||||||
import { MVideoImportDefault, MVideoImportDefaultFiles, MVideoImportVideo } from '@server/types/models/video/video-import'
|
import { MVideoImportDefault, MVideoImportDefaultFiles, MVideoImportVideo } from '@server/types/models/video/video-import'
|
||||||
import {
|
import {
|
||||||
VideoImportPayload,
|
VideoImportPayload,
|
||||||
|
@ -167,49 +169,66 @@ async function processFile (downloader: () => Promise<string>, videoImport: MVid
|
||||||
|
|
||||||
// Process thumbnail
|
// Process thumbnail
|
||||||
let thumbnailModel: MThumbnail
|
let thumbnailModel: MThumbnail
|
||||||
|
let thumbnailSave: object
|
||||||
if (options.generateThumbnail) {
|
if (options.generateThumbnail) {
|
||||||
thumbnailModel = await generateVideoMiniature(videoImportWithFiles.Video, videoFile, ThumbnailType.MINIATURE)
|
thumbnailModel = await generateVideoMiniature(videoImportWithFiles.Video, videoFile, ThumbnailType.MINIATURE)
|
||||||
|
thumbnailSave = thumbnailModel.toJSON()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process preview
|
// Process preview
|
||||||
let previewModel: MThumbnail
|
let previewModel: MThumbnail
|
||||||
|
let previewSave: object
|
||||||
if (options.generatePreview) {
|
if (options.generatePreview) {
|
||||||
previewModel = await generateVideoMiniature(videoImportWithFiles.Video, videoFile, ThumbnailType.PREVIEW)
|
previewModel = await generateVideoMiniature(videoImportWithFiles.Video, videoFile, ThumbnailType.PREVIEW)
|
||||||
|
previewSave = previewModel.toJSON()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create torrent
|
// Create torrent
|
||||||
await createTorrentAndSetInfoHash(videoImportWithFiles.Video, videoFile)
|
await createTorrentAndSetInfoHash(videoImportWithFiles.Video, videoFile)
|
||||||
|
|
||||||
const { videoImportUpdated, video } = await sequelizeTypescript.transaction(async t => {
|
const videoFileSave = videoFile.toJSON()
|
||||||
const videoImportToUpdate = videoImportWithFiles as MVideoImportVideo
|
|
||||||
|
|
||||||
// Refresh video
|
const { videoImportUpdated, video } = await retryTransactionWrapper(() => {
|
||||||
const video = await VideoModel.load(videoImportToUpdate.videoId, t)
|
return sequelizeTypescript.transaction(async t => {
|
||||||
if (!video) throw new Error('Video linked to import ' + videoImportToUpdate.videoId + ' does not exist anymore.')
|
const videoImportToUpdate = videoImportWithFiles as MVideoImportVideo
|
||||||
|
|
||||||
const videoFileCreated = await videoFile.save({ transaction: t })
|
// Refresh video
|
||||||
videoImportToUpdate.Video = Object.assign(video, { VideoFiles: [ videoFileCreated ] })
|
const video = await VideoModel.load(videoImportToUpdate.videoId, t)
|
||||||
|
if (!video) throw new Error('Video linked to import ' + videoImportToUpdate.videoId + ' does not exist anymore.')
|
||||||
|
|
||||||
// Update video DB object
|
const videoFileCreated = await videoFile.save({ transaction: t })
|
||||||
video.duration = duration
|
|
||||||
video.state = CONFIG.TRANSCODING.ENABLED ? VideoState.TO_TRANSCODE : VideoState.PUBLISHED
|
|
||||||
await video.save({ transaction: t })
|
|
||||||
|
|
||||||
if (thumbnailModel) await video.addAndSaveThumbnail(thumbnailModel, t)
|
// Update video DB object
|
||||||
if (previewModel) await video.addAndSaveThumbnail(previewModel, t)
|
video.duration = duration
|
||||||
|
video.state = CONFIG.TRANSCODING.ENABLED ? VideoState.TO_TRANSCODE : VideoState.PUBLISHED
|
||||||
|
await video.save({ transaction: t })
|
||||||
|
|
||||||
// Now we can federate the video (reload from database, we need more attributes)
|
if (thumbnailModel) await video.addAndSaveThumbnail(thumbnailModel, t)
|
||||||
const videoForFederation = await VideoModel.loadAndPopulateAccountAndServerAndTags(video.uuid, t)
|
if (previewModel) await video.addAndSaveThumbnail(previewModel, t)
|
||||||
await federateVideoIfNeeded(videoForFederation, true, t)
|
|
||||||
|
|
||||||
// Update video import object
|
// Now we can federate the video (reload from database, we need more attributes)
|
||||||
videoImportToUpdate.state = VideoImportState.SUCCESS
|
const videoForFederation = await VideoModel.loadAndPopulateAccountAndServerAndTags(video.uuid, t)
|
||||||
const videoImportUpdated = await videoImportToUpdate.save({ transaction: t }) as MVideoImportVideo
|
await federateVideoIfNeeded(videoForFederation, true, t)
|
||||||
videoImportUpdated.Video = video
|
|
||||||
|
|
||||||
logger.info('Video %s imported.', video.uuid)
|
// Update video import object
|
||||||
|
videoImportToUpdate.state = VideoImportState.SUCCESS
|
||||||
|
const videoImportUpdated = await videoImportToUpdate.save({ transaction: t }) as MVideoImportVideo
|
||||||
|
videoImportUpdated.Video = video
|
||||||
|
|
||||||
return { videoImportUpdated, video: videoForFederation }
|
videoImportToUpdate.Video = Object.assign(video, { VideoFiles: [ videoFileCreated ] })
|
||||||
|
|
||||||
|
logger.info('Video %s imported.', video.uuid)
|
||||||
|
|
||||||
|
return { videoImportUpdated, video: videoForFederation }
|
||||||
|
}).catch(err => {
|
||||||
|
// Reset fields
|
||||||
|
if (thumbnailModel) thumbnailModel = new ThumbnailModel(thumbnailSave)
|
||||||
|
if (previewModel) previewModel = new ThumbnailModel(previewSave)
|
||||||
|
|
||||||
|
videoFile = new VideoFileModel(videoFileSave)
|
||||||
|
|
||||||
|
throw err
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
Notifier.Instance.notifyOnFinishedVideoImport(videoImportUpdated, true)
|
Notifier.Instance.notifyOnFinishedVideoImport(videoImportUpdated, true)
|
||||||
|
|
|
@ -21,6 +21,7 @@ import { CONSTRAINTS_FIELDS, VIDEO_IMPORT_STATES } from '../../initializers/cons
|
||||||
import { UserModel } from '../account/user'
|
import { UserModel } from '../account/user'
|
||||||
import { getSort, throwIfNotValid } from '../utils'
|
import { getSort, throwIfNotValid } from '../utils'
|
||||||
import { ScopeNames as VideoModelScopeNames, VideoModel } from './video'
|
import { ScopeNames as VideoModelScopeNames, VideoModel } from './video'
|
||||||
|
import { afterCommitIfTransaction } from '@server/helpers/database-utils'
|
||||||
|
|
||||||
@DefaultScope(() => ({
|
@DefaultScope(() => ({
|
||||||
include: [
|
include: [
|
||||||
|
@ -113,7 +114,7 @@ export class VideoImportModel extends Model {
|
||||||
@AfterUpdate
|
@AfterUpdate
|
||||||
static deleteVideoIfFailed (instance: VideoImportModel, options) {
|
static deleteVideoIfFailed (instance: VideoImportModel, options) {
|
||||||
if (instance.state === VideoImportState.FAILED) {
|
if (instance.state === VideoImportState.FAILED) {
|
||||||
return instance.Video.destroy({ transaction: options.transaction })
|
return afterCommitIfTransaction(options.transaction, () => instance.Video.destroy())
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined
|
return undefined
|
||||||
|
|
|
@ -25,7 +25,7 @@ function getYoutubeHDRVideoUrl () {
|
||||||
* - 337 (2160p webm vp9.2 HDR)
|
* - 337 (2160p webm vp9.2 HDR)
|
||||||
* - 401 (2160p mp4 av01 HDR)
|
* - 401 (2160p mp4 av01 HDR)
|
||||||
*/
|
*/
|
||||||
return 'https://www.youtube.com/watch?v=MSJ25EqI19c'
|
return 'https://www.youtube.com/watch?v=qR5vOXbZsI4'
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMagnetURI () {
|
function getMagnetURI () {
|
||||||
|
|
Loading…
Reference in New Issue