Kaynağa Gözat

Merge pull request #4432 from ThomasWaldmann/lrucache-clean-old

lrucache: regularly remove old FDs, fixes #4427
TW 6 yıl önce
ebeveyn
işleme
09681b6b18
2 değiştirilmiş dosya ile 16 ekleme ve 10 silme
  1. 0 1
      src/borg/lrucache.py
  2. 16 9
      src/borg/repository.py

+ 0 - 1
src/borg/lrucache.py

@@ -50,7 +50,6 @@ class LRUCache:
             self._dispose(value)
         self._cache.clear()
 
-    # useful for testing
     def items(self):
         return self._cache.items()
 

+ 16 - 9
src/borg/repository.py

@@ -1216,6 +1216,7 @@ class LoggedIO:
         self.segments_per_dir = segments_per_dir
         self.offset = 0
         self._write_fd = None
+        self._fds_cleaned = 0
 
     def close(self):
         self.close_segment()
@@ -1346,20 +1347,26 @@ class LoggedIO:
             self.fds[segment] = (now, fd)
             return fd
 
+        def clean_old():
+            # we regularly get rid of all old FDs here:
+            if now - self._fds_cleaned > FD_MAX_AGE // 8:
+                self._fds_cleaned = now
+                for k, ts_fd in list(self.fds.items()):
+                    ts, fd = ts_fd
+                    if now - ts > FD_MAX_AGE:
+                        # we do not want to touch long-unused file handles to
+                        # avoid ESTALE issues (e.g. on network filesystems).
+                        del self.fds[k]
+
+        clean_old()
         try:
             ts, fd = self.fds[segment]
         except KeyError:
             fd = open_fd()
         else:
-            if now - ts > FD_MAX_AGE:
-                # we do not want to touch long-unused file handles to
-                # avoid ESTALE issues (e.g. on network filesystems).
-                del self.fds[segment]
-                fd = open_fd()
-            else:
-                # fd is fresh enough, so we use it.
-                # also, we update the timestamp of the lru cache entry.
-                self.fds.upd(segment, (now, fd))
+            # we only have fresh enough stuff here.
+            # update the timestamp of the lru cache entry.
+            self.fds.upd(segment, (now, fd))
         return fd
 
     def close_segment(self):