]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/commitdiff
Lock when removing video files
authorChocobozzz <me@florianbigard.com>
Mon, 22 May 2023 08:16:45 +0000 (10:16 +0200)
committerChocobozzz <me@florianbigard.com>
Mon, 22 May 2023 09:06:04 +0000 (11:06 +0200)
server/lib/video-file.ts

index 8fcc3c2532677eb419e5e89c24bef41358286fdc..88d48c945d3c7bcc8d329709dd6d2f729fdb1054 100644 (file)
@@ -8,6 +8,7 @@ import { ffprobePromise, getVideoStreamDimensionsInfo, getVideoStreamFPS, isAudi
 import { VideoFileMetadata, VideoResolution } from '@shared/models'
 import { lTags } from './object-storage/shared'
 import { generateHLSVideoFilename, generateWebTorrentVideoFilename } from './paths'
+import { VideoPathManager } from './video-path-manager'
 
 async function buildNewFile (options: {
   path: string
@@ -44,10 +45,16 @@ async function removeHLSPlaylist (video: MVideoWithAllFiles) {
   const hls = video.getHLSPlaylist()
   if (!hls) return
 
-  await video.removeStreamingPlaylistFiles(hls)
-  await hls.destroy()
+  const videoFileMutexReleaser = await VideoPathManager.Instance.lockFiles(video.uuid)
 
-  video.VideoStreamingPlaylists = video.VideoStreamingPlaylists.filter(p => p.id !== hls.id)
+  try {
+    await video.removeStreamingPlaylistFiles(hls)
+    await hls.destroy()
+
+    video.VideoStreamingPlaylists = video.VideoStreamingPlaylists.filter(p => p.id !== hls.id)
+  } finally {
+    videoFileMutexReleaser()
+  }
 }
 
 async function removeHLSFile (video: MVideoWithAllFiles, fileToDeleteId: number) {
@@ -61,11 +68,17 @@ async function removeHLSFile (video: MVideoWithAllFiles, fileToDeleteId: number)
     return undefined
   }
 
-  const toDelete = files.find(f => f.id === fileToDeleteId)
-  await video.removeStreamingPlaylistVideoFile(video.getHLSPlaylist(), toDelete)
-  await toDelete.destroy()
+  const videoFileMutexReleaser = await VideoPathManager.Instance.lockFiles(video.uuid)
 
-  hls.VideoFiles = hls.VideoFiles.filter(f => f.id !== toDelete.id)
+  try {
+    const toDelete = files.find(f => f.id === fileToDeleteId)
+    await video.removeStreamingPlaylistVideoFile(video.getHLSPlaylist(), toDelete)
+    await toDelete.destroy()
+
+    hls.VideoFiles = hls.VideoFiles.filter(f => f.id !== toDelete.id)
+  } finally {
+    videoFileMutexReleaser()
+  }
 
   return hls
 }
@@ -73,12 +86,18 @@ async function removeHLSFile (video: MVideoWithAllFiles, fileToDeleteId: number)
 // ---------------------------------------------------------------------------
 
 async function removeAllWebTorrentFiles (video: MVideoWithAllFiles) {
-  for (const file of video.VideoFiles) {
-    await video.removeWebTorrentFile(file)
-    await file.destroy()
-  }
+  const videoFileMutexReleaser = await VideoPathManager.Instance.lockFiles(video.uuid)
+
+  try {
+    for (const file of video.VideoFiles) {
+      await video.removeWebTorrentFile(file)
+      await file.destroy()
+    }
 
-  video.VideoFiles = []
+    video.VideoFiles = []
+  } finally {
+    videoFileMutexReleaser()
+  }
 
   return video
 }
@@ -90,11 +109,16 @@ async function removeWebTorrentFile (video: MVideoWithAllFiles, fileToDeleteId:
     return removeAllWebTorrentFiles(video)
   }
 
-  const toDelete = files.find(f => f.id === fileToDeleteId)
-  await video.removeWebTorrentFile(toDelete)
-  await toDelete.destroy()
+  const videoFileMutexReleaser = await VideoPathManager.Instance.lockFiles(video.uuid)
+  try {
+    const toDelete = files.find(f => f.id === fileToDeleteId)
+    await video.removeWebTorrentFile(toDelete)
+    await toDelete.destroy()
 
-  video.VideoFiles = files.filter(f => f.id !== toDelete.id)
+    video.VideoFiles = files.filter(f => f.id !== toDelete.id)
+  } finally {
+    videoFileMutexReleaser()
+  }
 
   return video
 }