]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/commitdiff
Lock files to generate torrents/move files
authorChocobozzz <me@florianbigard.com>
Tue, 25 Oct 2022 09:50:44 +0000 (11:50 +0200)
committerChocobozzz <me@florianbigard.com>
Tue, 25 Oct 2022 09:50:44 +0000 (11:50 +0200)
server/lib/job-queue/handlers/manage-video-torrent.ts
server/lib/job-queue/handlers/move-to-object-storage.ts

index 425915c96891348f34b0414b2c617d9e896a48f2..cef93afda011cfd932df166112272a20817b7970 100644 (file)
@@ -1,5 +1,7 @@
 import { Job } from 'bullmq'
+import { extractVideo } from '@server/helpers/video'
 import { createTorrentAndSetInfoHash, updateTorrentMetadata } from '@server/helpers/webtorrent'
+import { VideoPathManager } from '@server/lib/video-path-manager'
 import { VideoModel } from '@server/models/video/video'
 import { VideoFileModel } from '@server/models/video/video-file'
 import { VideoStreamingPlaylistModel } from '@server/models/video/video-streaming-playlist'
@@ -30,17 +32,23 @@ async function doCreateAction (payload: ManageVideoTorrentPayload & { action: 'c
 
   if (!video || !file) return
 
-  await createTorrentAndSetInfoHash(video, file)
+  const fileMutexReleaser = await VideoPathManager.Instance.lockFiles(video.uuid)
 
-  // Refresh videoFile because the createTorrentAndSetInfoHash could be long
-  const refreshedFile = await VideoFileModel.loadWithVideo(file.id)
-  // File does not exist anymore, remove the generated torrent
-  if (!refreshedFile) return file.removeTorrent()
+  try {
+    await createTorrentAndSetInfoHash(video, file)
 
-  refreshedFile.infoHash = file.infoHash
-  refreshedFile.torrentFilename = file.torrentFilename
+    // Refresh videoFile because the createTorrentAndSetInfoHash could be long
+    const refreshedFile = await VideoFileModel.loadWithVideo(file.id)
+    // File does not exist anymore, remove the generated torrent
+    if (!refreshedFile) return file.removeTorrent()
 
-  return refreshedFile.save()
+    refreshedFile.infoHash = file.infoHash
+    refreshedFile.torrentFilename = file.torrentFilename
+
+    await refreshedFile.save()
+  } finally {
+    fileMutexReleaser()
+  }
 }
 
 async function doUpdateMetadataAction (payload: ManageVideoTorrentPayload & { action: 'update-metadata' }) {
@@ -52,9 +60,16 @@ async function doUpdateMetadataAction (payload: ManageVideoTorrentPayload & { ac
 
   if ((!video && !streamingPlaylist) || !file) return
 
-  await updateTorrentMetadata(video || streamingPlaylist, file)
+  const extractedVideo = extractVideo(video || streamingPlaylist)
+  const fileMutexReleaser = await VideoPathManager.Instance.lockFiles(extractedVideo.uuid)
 
-  await file.save()
+  try {
+    await updateTorrentMetadata(video || streamingPlaylist, file)
+
+    await file.save()
+  } finally {
+    fileMutexReleaser()
+  }
 }
 
 async function loadVideoOrLog (videoId: number) {
index 0b68555d1fa26c5f67ea414b825b6d3a3966fd29..a1530cc573daaf3415da380c4dec199b2ec17fbd 100644 (file)
@@ -28,6 +28,8 @@ export async function processMoveToObjectStorage (job: Job) {
 
   const lTags = lTagsBase(video.uuid, video.url)
 
+  const fileMutexReleaser = await VideoPathManager.Instance.lockFiles(video.uuid)
+
   try {
     if (video.VideoFiles) {
       logger.debug('Moving %d webtorrent files for video %s.', video.VideoFiles.length, video.uuid, lTags)
@@ -49,6 +51,10 @@ export async function processMoveToObjectStorage (job: Job) {
     }
   } catch (err) {
     await onMoveToObjectStorageFailure(job, err)
+
+    throw err
+  } finally {
+    fileMutexReleaser()
   }
 
   return payload.videoUUID