From d61893f7236abbed30c25b1823e6ecad93a8e8dd Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 25 Feb 2021 13:56:07 +0100 Subject: Async torrent creation --- server/controllers/api/videos/index.ts | 38 +++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) (limited to 'server/controllers/api') diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts index e89315930..58ab72370 100644 --- a/server/controllers/api/videos/index.ts +++ b/server/controllers/api/videos/index.ts @@ -9,12 +9,12 @@ import { LiveManager } from '@server/lib/live-manager' import { addOptimizeOrMergeAudioJob, buildLocalVideoFromReq, buildVideoThumbnailsFromReq, setVideoTags } from '@server/lib/video' import { generateVideoFilename, getVideoFilePath } from '@server/lib/video-paths' import { getServerActor } from '@server/models/application/application' -import { MVideoFullLight } from '@server/types/models' +import { MVideo, MVideoFile, MVideoFullLight } from '@server/types/models' import { VideoCreate, VideoState, VideoUpdate } from '../../../../shared' import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' import { VideoFilter } from '../../../../shared/models/videos/video-query.type' import { auditLoggerFactory, getAuditIdFromRes, VideoAuditView } from '../../../helpers/audit-logger' -import { resetSequelizeInstance } from '../../../helpers/database-utils' +import { resetSequelizeInstance, retryTransactionWrapper } from '../../../helpers/database-utils' import { buildNSFWFilter, createReqFiles, getCountVideos } from '../../../helpers/express-utils' import { getMetadataFromFile, getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffprobe-utils' import { logger } from '../../../helpers/logger' @@ -221,9 +221,6 @@ async function addVideo (req: express.Request, res: express.Response) { fallback: type => generateVideoMiniature({ video, videoFile, type }) }) - // Create the torrent file - await createTorrentAndSetInfoHash(video, videoFile) - const { videoCreated } = await sequelizeTypescript.transaction(async t => { const sequelizeOptions = { transaction: t } @@ -258,7 +255,6 @@ async function addVideo (req: express.Request, res: express.Response) { isNew: true, transaction: t }) - await federateVideoIfNeeded(video, true, t) auditLogger.create(getAuditIdFromRes(res), new VideoAuditView(videoCreated.toFormattedDetailsJSON())) logger.info('Video with name %s and uuid %s created.', videoInfo.name, videoCreated.uuid) @@ -266,7 +262,21 @@ async function addVideo (req: express.Request, res: express.Response) { return { videoCreated } }) - Notifier.Instance.notifyOnNewVideoIfNeeded(videoCreated) + // Create the torrent file in async way because it could be long + createTorrentAndSetInfoHashAsync(video, videoFile) + .catch(err => logger.error('Cannot create torrent file for video %s', video.url, { err })) + .then(() => VideoModel.loadAndPopulateAccountAndServerAndTags(video.id)) + .then(refreshedVideo => { + if (!refreshedVideo) return + + // Only federate and notify after the torrent creation + Notifier.Instance.notifyOnNewVideoIfNeeded(refreshedVideo) + + return retryTransactionWrapper(() => { + return sequelizeTypescript.transaction(t => federateVideoIfNeeded(refreshedVideo, true, t)) + }) + }) + .catch(err => logger.error('Cannot federate or notify video creation %s', video.url, { err })) if (video.state === VideoState.TO_TRANSCODE) { await addOptimizeOrMergeAudioJob(videoCreated, videoFile, res.locals.oauth.token.User) @@ -526,3 +536,17 @@ async function removeVideo (req: express.Request, res: express.Response) { .status(HttpStatusCode.NO_CONTENT_204) .end() } + +async function createTorrentAndSetInfoHashAsync (video: MVideo, fileArg: MVideoFile) { + await createTorrentAndSetInfoHash(video, fileArg) + + // Refresh videoFile because the createTorrentAndSetInfoHash could be long + const refreshedFile = await VideoFileModel.loadWithVideo(fileArg.id) + // File does not exist anymore, remove the generated torrent + if (!refreshedFile) return fileArg.removeTorrent() + + refreshedFile.infoHash = fileArg.infoHash + refreshedFile.torrentFilename = fileArg.torrentFilename + + return refreshedFile.save() +} -- cgit v1.2.3