Просмотр исходного кода

[ContentCacheManager] write streams to disk atomically

Use an intermediate file for writing to disk, then rename to the target.
Jakob Ackermann 5 лет назад
Родитель
Сommit
6b9c8bced6
1 измененных файлов с 15 добавлено и 5 удалено
  1. 15 5
      services/clsi/app/js/ContentCacheManager.js

+ 15 - 5
services/clsi/app/js/ContentCacheManager.js

@@ -100,17 +100,27 @@ async function writePdfStream(dir, hash, buffers) {
     //  ETags used for client side caching via browser internals.
     return false
   } catch (e) {}
-  const file = await fs.promises.open(filename, 'w')
+  const atomicWriteFilename = filename + '~'
+  const file = await fs.promises.open(atomicWriteFilename, 'w')
   if (Settings.enablePdfCachingDark) {
     // Write an empty file in dark mode.
     buffers = []
   }
   try {
-    for (const buffer of buffers) {
-      await file.write(buffer)
+    try {
+      for (const buffer of buffers) {
+        await file.write(buffer)
+      }
+    } finally {
+      await file.close()
+    }
+    await fs.promises.rename(atomicWriteFilename, filename)
+  } catch (err) {
+    try {
+      await fs.promises.unlink(atomicWriteFilename)
+    } catch (_) {
+      throw err
     }
-  } finally {
-    await file.close()
   }
   return true
 }