Mercurial > hg
changeset 50237:a3b1ab5f5dee stable
dirstate: deal with read-race for pure python code
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 19:01:20 +0100 |
parents | 53f196622699 |
children | c9066fc609ef |
files | mercurial/dirstatemap.py tests/test-dirstate-read-race.t |
diffstat | 2 files changed, 37 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/dirstatemap.py Wed Mar 01 16:05:28 2023 +0100 +++ b/mercurial/dirstatemap.py Tue Feb 28 19:01:20 2023 +0100 @@ -37,6 +37,9 @@ WRITE_MODE_FORCE_APPEND = 2 +V2_MAX_READ_ATTEMPTS = 5 + + class _dirstatemapcommon: """ Methods that are identical for both implementations of the dirstatemap @@ -125,6 +128,21 @@ return self._docket def _read_v2_data(self): + data = None + attempts = 0 + while attempts < V2_MAX_READ_ATTEMPTS: + attempts += 1 + try: + data = self._opener.read(self.docket.data_filename()) + except FileNotFoundError: + # read race detected between docket and data file + # reload the docket and retry + self._docket = None + if data is None: + assert attempts >= V2_MAX_READ_ATTEMPTS + msg = b"dirstate read race happened %d times in a row" + msg %= attempts + raise error.Abort(msg) return self._opener.read(self.docket.data_filename()) def write_v2_no_append(self, tr, st, meta, packed):
--- a/tests/test-dirstate-read-race.t Wed Mar 01 16:05:28 2023 +0100 +++ b/tests/test-dirstate-read-race.t Tue Feb 28 19:01:20 2023 +0100 @@ -217,8 +217,12 @@ #endif #else $ 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) #endif #endif #endif @@ -318,8 +322,12 @@ #endif #else $ 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! #endif #endif #endif @@ -452,8 +460,11 @@ #endif #else $ 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) #endif #endif #endif @@ -542,8 +553,12 @@ #endif #else $ 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) #endif #endif #endif