mirror of https://github.com/Chocobozzz/PeerTube
Optimise transaction for video upload
parent
cadb46d832
commit
e11f68a356
|
@ -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)
|
||||||
|
|
|
@ -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')
|
||||||
|
|
|
@ -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'
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue