فهرست منبع

Merge pull request #235 from overleaf/jpa-atomic-writes

[ContentCacheManager] write streams to disk atomically
Jakob Ackermann 5 سال پیش
والد
کامیت
e787106eed
1فایلهای تغییر یافته به همراه15 افزوده شده و 5 حذف شده
  1. 15 5
      services/clsi/app/js/ContentCacheManager.js

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

@@ -121,17 +121,27 @@ async function writePdfStream(dir, hash, buffers) {
     //  ETags used for client side caching via browser internals.
     //  ETags used for client side caching via browser internals.
     return false
     return false
   } catch (e) {}
   } catch (e) {}
-  const file = await fs.promises.open(filename, 'w')
+  const atomicWriteFilename = filename + '~'
+  const file = await fs.promises.open(atomicWriteFilename, 'w')
   if (Settings.enablePdfCachingDark) {
   if (Settings.enablePdfCachingDark) {
     // Write an empty file in dark mode.
     // Write an empty file in dark mode.
     buffers = []
     buffers = []
   }
   }
   try {
   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
   return true
 }
 }