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.
--- 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