Make smart futures avoid polling.
[python_utils.git] / lockfile.py
index ee8c2559606b0fc9488d3c2bc5ed772ec70254a0..1e0516bf75a340b4a15629141cdfbfb83fc3485c 100644 (file)
@@ -28,7 +28,14 @@ class LockFileContents:
 
 class LockFile(object):
     """A file locking mechanism that has context-manager support so you
-    can use it in a with statement.
+    can use it in a with statement.  e.g.
+
+    with LockFile('./foo.lock'):
+        # do a bunch of stuff... if the process dies we have a signal
+        # handler to do cleanup.  Other code (in this process or another)
+        # that tries to take the same lockfile will block.  There is also
+        # some logic for detecting stale locks.
+
     """
 
     def __init__(
@@ -37,9 +44,11 @@ class LockFile(object):
             *,
             do_signal_cleanup: bool = True,
             expiration_timestamp: Optional[float] = None,
+            override_command: Optional[str] = None,
     ) -> None:
         self.is_locked = False
         self.lockfile = lockfile_path
+        self.override_command = override_command
         if do_signal_cleanup:
             signal.signal(signal.SIGINT, self._signal)
             signal.signal(signal.SIGTERM, self._signal)
@@ -117,10 +126,15 @@ class LockFile(object):
             self.release()
 
     def _get_lockfile_contents(self) -> str:
+        if self.override_command:
+            cmd = self.override_command
+        else:
+            cmd = ' '.join(sys.argv)
+        print(cmd)
         contents = LockFileContents(
             pid = os.getpid(),
-            commandline = ' '.join(sys.argv),
-            expiration_timestamp = self.expiration_timestamp
+            commandline = cmd,
+            expiration_timestamp = self.expiration_timestamp,
         )
         return json.dumps(contents.__dict__)