changeset 50238:c9066fc609ef stable

dirstate: deal with read-race for python code using rust object If we cannot read the dirstate data, this is probably because a writing process wrote it under our feet. So refresh the docket and try again a handful of time.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Tue, 28 Feb 2023 23:35:52 +0100
parents a3b1ab5f5dee
children 491f3dd080eb
files mercurial/dirstatemap.py tests/test-dirstate-read-race.t
diffstat 2 files changed, 25 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/dirstatemap.py	Tue Feb 28 19:01:20 2023 +0100
+++ b/mercurial/dirstatemap.py	Tue Feb 28 23:35:52 2023 +0100
@@ -133,6 +133,7 @@
         while attempts < V2_MAX_READ_ATTEMPTS:
             attempts += 1
             try:
+                # TODO: use mmap when possible
                 data = self._opener.read(self.docket.data_filename())
             except FileNotFoundError:
                 # read race detected between docket and data file
@@ -568,14 +569,12 @@
 
             testing.wait_on_cfg(self._ui, b'dirstate.pre-read-file')
             if self._use_dirstate_v2:
-                if self.docket.uuid:
-                    testing.wait_on_cfg(
-                        self._ui, b'dirstate.post-docket-read-file'
-                    )
-                    # TODO: use mmap when possible
-                    data = self._opener.read(self.docket.data_filename())
+                self.docket  # load the data if needed
+                testing.wait_on_cfg(self._ui, b'dirstate.post-docket-read-file')
+                if not self.docket.uuid:
+                    data = b''
                 else:
-                    data = b''
+                    data = self._read_v2_data()
                 self._map = rustmod.DirstateMap.new_v2(
                     data, self.docket.data_size, self.docket.tree_metadata
                 )
--- a/tests/test-dirstate-read-race.t	Tue Feb 28 19:01:20 2023 +0100
+++ b/tests/test-dirstate-read-race.t	Tue Feb 28 23:35:52 2023 +0100
@@ -204,8 +204,12 @@
 #if rust
 #if dirstate-v2-rewrite
   $ cat $TESTTMP/status-race-lock.out
+  A dir/n
+  A dir/o
+  R dir/nested/m
+  ? p
+  ? q
   $ cat $TESTTMP/status-race-lock.log
-  abort: $ENOENT$: '$TESTTMP/race-with-add/.hg/dirstate.* (glob)
 #else
   $ cat $TESTTMP/status-race-lock.out
   A dir/o
@@ -309,8 +313,12 @@
 #if rust
 #if dirstate-v2-rewrite
   $ cat $TESTTMP/status-race-lock.out
+  M dir/o
+  ? dir/n
+  ? p
+  ? q
   $ cat $TESTTMP/status-race-lock.log
-  abort: $ENOENT$: '$TESTTMP/race-with-commit/.hg/dirstate.* (glob)
+  warning: ignoring unknown working parent 02a67a77ee9b!
 #else
   $ cat $TESTTMP/status-race-lock.out
   A dir/o
@@ -441,8 +449,11 @@
 #if rust
 #if dirstate-v2-rewrite
   $ cat $TESTTMP/status-race-lock.out
+  A dir/o
+  ? dir/n
+  ? p
+  ? q
   $ cat $TESTTMP/status-race-lock.log
-  abort: $ENOENT$: '$TESTTMP/race-with-update/.hg/dirstate.* (glob)
 #else
   $ cat $TESTTMP/status-race-lock.out
   A dir/o
@@ -540,8 +551,12 @@
 #if rust
 #if dirstate-v2-rewrite
   $ cat $TESTTMP/status-race-lock.out
+  A dir/o
+  R dir/nested/m
+  ? dir/n
+  ? p
+  ? q
   $ cat $TESTTMP/status-race-lock.log
-  abort: $ENOENT$: '$TESTTMP/race-with-status/.hg/dirstate.* (glob)
 #else
   $ cat $TESTTMP/status-race-lock.out
   A dir/o