Optimise transaction for video upload

pull/159/head
Chocobozzz 2017-12-08 10:08:36 +01:00
parent cadb46d832
commit e11f68a356
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
3 changed files with 53 additions and 57 deletions

View File

@ -164,73 +164,72 @@ async function addVideoRetryWrapper (req: express.Request, res: express.Response
}).end() }).end()
} }
function addVideo (req: express.Request, res: express.Response, videoPhysicalFile: Express.Multer.File) { async function addVideo (req: express.Request, res: express.Response, videoPhysicalFile: Express.Multer.File) {
const videoInfo: VideoCreate = req.body const videoInfo: VideoCreate = req.body
// Prepare data so we don't block the transaction
const videoData = {
name: videoInfo.name,
remote: false,
extname: extname(videoPhysicalFile.filename),
category: videoInfo.category,
licence: videoInfo.licence,
language: videoInfo.language,
nsfw: videoInfo.nsfw,
description: videoInfo.description,
privacy: videoInfo.privacy,
duration: videoPhysicalFile['duration'], // duration was added by a previous middleware
channelId: res.locals.videoChannel.id
}
const video = db.Video.build(videoData)
video.url = getVideoActivityPubUrl(video)
const videoFilePath = join(CONFIG.STORAGE.VIDEOS_DIR, videoPhysicalFile.filename)
const videoFileHeight = await getVideoFileHeight(videoFilePath)
const videoFileData = {
extname: extname(videoPhysicalFile.filename),
resolution: videoFileHeight,
size: videoPhysicalFile.size
}
const videoFile = db.VideoFile.build(videoFileData)
const videoDir = CONFIG.STORAGE.VIDEOS_DIR
const source = join(videoDir, videoPhysicalFile.filename)
const destination = join(videoDir, video.getVideoFilename(videoFile))
await renamePromise(source, destination)
// This is important in case if there is another attempt in the retry process
videoPhysicalFile.filename = video.getVideoFilename(videoFile)
const tasks = []
tasks.push(
video.createTorrentAndSetInfoHash(videoFile),
video.createThumbnail(videoFile),
video.createPreview(videoFile)
)
await Promise.all(tasks)
return db.sequelize.transaction(async t => { return db.sequelize.transaction(async t => {
const sequelizeOptions = { transaction: t } const sequelizeOptions = { transaction: t }
const videoData = {
name: videoInfo.name,
remote: false,
extname: extname(videoPhysicalFile.filename),
category: videoInfo.category,
licence: videoInfo.licence,
language: videoInfo.language,
nsfw: videoInfo.nsfw,
description: videoInfo.description,
privacy: videoInfo.privacy,
duration: videoPhysicalFile['duration'], // duration was added by a previous middleware
channelId: res.locals.videoChannel.id
}
const video = db.Video.build(videoData)
video.url = getVideoActivityPubUrl(video)
const videoFilePath = join(CONFIG.STORAGE.VIDEOS_DIR, videoPhysicalFile.filename)
const videoFileHeight = await getVideoFileHeight(videoFilePath)
const videoFileData = {
extname: extname(videoPhysicalFile.filename),
resolution: videoFileHeight,
size: videoPhysicalFile.size
}
const videoFile = db.VideoFile.build(videoFileData)
const videoDir = CONFIG.STORAGE.VIDEOS_DIR
const source = join(videoDir, videoPhysicalFile.filename)
const destination = join(videoDir, video.getVideoFilename(videoFile))
await renamePromise(source, destination)
// This is important in case if there is another attempt in the retry process
videoPhysicalFile.filename = video.getVideoFilename(videoFile)
const tasks = []
tasks.push(
video.createTorrentAndSetInfoHash(videoFile),
video.createThumbnail(videoFile),
video.createPreview(videoFile)
)
if (CONFIG.TRANSCODING.ENABLED === true) { if (CONFIG.TRANSCODING.ENABLED === true) {
// Put uuid because we don't have id auto incremented for now // Put uuid because we don't have id auto incremented for now
const dataInput = { const dataInput = {
videoUUID: video.uuid videoUUID: video.uuid
} }
tasks.push( await transcodingJobScheduler.createJob(t, 'videoFileOptimizer', dataInput)
transcodingJobScheduler.createJob(t, 'videoFileOptimizer', dataInput)
)
} }
await Promise.all(tasks)
const videoCreated = await video.save(sequelizeOptions) const videoCreated = await video.save(sequelizeOptions)
// Do not forget to add video channel information to the created video // Do not forget to add video channel information to the created video
videoCreated.VideoChannel = res.locals.videoChannel videoCreated.VideoChannel = res.locals.videoChannel
videoFile.videoId = video.id videoFile.videoId = video.id
await videoFile.save(sequelizeOptions) await videoFile.save(sequelizeOptions)
video.VideoFiles = [videoFile]
video.VideoFiles = [ videoFile ]
if (videoInfo.tags) { if (videoInfo.tags) {
const tagInstances = await db.Tag.findOrCreateTags(videoInfo.tags, t) const tagInstances = await db.Tag.findOrCreateTags(videoInfo.tags, t)

View File

@ -364,7 +364,7 @@ describe('Test a single server', function () {
'video_short1.webm', 'video_short2.webm', 'video_short3.webm' 'video_short1.webm', 'video_short2.webm', 'video_short3.webm'
] ]
// const tasks: Promise<any>[] = [] const tasks: Promise<any>[] = []
for (const video of videos) { for (const video of videos) {
const videoAttributes = { const videoAttributes = {
name: video + ' name', name: video + ' name',
@ -378,13 +378,10 @@ describe('Test a single server', function () {
} }
const p = uploadVideo(server.url, server.accessToken, videoAttributes) const p = uploadVideo(server.url, server.accessToken, videoAttributes)
await p tasks.push(p)
} }
// FIXME: concurrent uploads does not work :(
// tasks.push(p) await Promise.all(tasks)
// }
//
// await Promise.all(tasks)
}) })
it('Should have the correct durations', async function () { it('Should have the correct durations', async function () {
@ -712,7 +709,7 @@ describe('Test a single server', function () {
const filePath = join(__dirname, '..', 'api', 'fixtures', 'video_short.webm') const filePath = join(__dirname, '..', 'api', 'fixtures', 'video_short.webm')
await req.attach('videofile', filePath) await req.attach('videofile', filePath)
.expect(204) .expect(200)
const res = await getVideosList(server.url) const res = await getVideosList(server.url)
const video = res.body.data.find(v => v.name === 'minimum parameters') const video = res.body.data.find(v => v.name === 'minimum parameters')

View File

@ -201,7 +201,7 @@ async function testVideoImage (url: string, imageName: string, imagePath: string
} }
} }
async function uploadVideo (url: string, accessToken: string, videoAttributesArg: VideoAttributes, specialStatus = 201) { async function uploadVideo (url: string, accessToken: string, videoAttributesArg: VideoAttributes, specialStatus = 200) {
const path = '/api/v1/videos/upload' const path = '/api/v1/videos/upload'
let defaultChannelId = '1' let defaultChannelId = '1'