changeset 138:a0ba822690f4 default tip

don't read our own file-writes!
author drewp@bigasterisk.com
date Thu, 01 Jun 2023 14:04:06 -0700
parents ae6821e203ac
children
files rdfdb/watched_files.py
diffstat 1 files changed, 15 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/rdfdb/watched_files.py	Thu Jun 01 14:03:31 2023 -0700
+++ b/rdfdb/watched_files.py	Thu Jun 01 14:04:06 2023 -0700
@@ -1,6 +1,8 @@
 import asyncio
 import dataclasses
 import logging
+import os
+import time
 from pathlib import Path
 from typing import Callable, Dict, Iterable, Optional, Type, Union
 
@@ -11,6 +13,7 @@
 
 MAX_FILE_DIRTY_SECS = 1
 
+
 class FileIsGone:
     pass
 
@@ -47,6 +50,10 @@
         self.fileEditEvents = asyncio.Queue()
         self.filesToWrite = asyncio.Queue()
 
+        # This object wrote the file such that its mtime is before the
+        # dict value.
+        self.committedBeforeTime: Dict[Path, float] = {}
+
         log.info("setup watches")
         for p in dirsToWatch:
             self._watchTree(p)
@@ -81,8 +88,11 @@
         tmpOut = Path(str(p) + ".rdfdb-temp")
         tmpOut.write_text(content)
 
-        self.lastWriteTimestamp = tmpOut.stat().st_mtime
         tmpOut.rename(p)
+        self.committedBeforeTime[p] = time.time()
+        mtime = p.stat().st_mtime
+        if not (mtime < self.committedBeforeTime[p]):
+            raise ValueError(f'clock catastrophe: {p} {mtime=} is not before wall clock time {self.committedBeforeTime[p]}')
 
         # p.write_text(content)
         # and don't trigger event, etc
@@ -191,7 +201,10 @@
         if p.name.endswith('.rdfdb-temp'):
             return
         log.debug(f'ino callback path={str(p)[-30:]!s:30} watchpath={str(iev.path)[-30:]!s:30} {iev.mask!r}')
-
+        mtime = os.path.getmtime(p)
+        if p in self.committedBeforeTime and mtime < self.committedBeforeTime[p]:
+            log.debug(f'looks like my own file-write from {self.committedBeforeTime[p]=} {mtime=}')
+            return
         if iev.mask == Mask.DELETE_SELF:
             self._genGoneEvent(p)
             if iev.watch is None: