comparison mercurial/dirstatemap.py @ 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
comparison
equal deleted inserted replaced
50236:53f196622699 50237:a3b1ab5f5dee
33 rangemask = 0x7FFFFFFF 33 rangemask = 0x7FFFFFFF
34 34
35 WRITE_MODE_AUTO = 0 35 WRITE_MODE_AUTO = 0
36 WRITE_MODE_FORCE_NEW = 1 36 WRITE_MODE_FORCE_NEW = 1
37 WRITE_MODE_FORCE_APPEND = 2 37 WRITE_MODE_FORCE_APPEND = 2
38
39
40 V2_MAX_READ_ATTEMPTS = 5
38 41
39 42
40 class _dirstatemapcommon: 43 class _dirstatemapcommon:
41 """ 44 """
42 Methods that are identical for both implementations of the dirstatemap 45 Methods that are identical for both implementations of the dirstatemap
123 self._readdirstatefile(), self._nodeconstants 126 self._readdirstatefile(), self._nodeconstants
124 ) 127 )
125 return self._docket 128 return self._docket
126 129
127 def _read_v2_data(self): 130 def _read_v2_data(self):
131 data = None
132 attempts = 0
133 while attempts < V2_MAX_READ_ATTEMPTS:
134 attempts += 1
135 try:
136 data = self._opener.read(self.docket.data_filename())
137 except FileNotFoundError:
138 # read race detected between docket and data file
139 # reload the docket and retry
140 self._docket = None
141 if data is None:
142 assert attempts >= V2_MAX_READ_ATTEMPTS
143 msg = b"dirstate read race happened %d times in a row"
144 msg %= attempts
145 raise error.Abort(msg)
128 return self._opener.read(self.docket.data_filename()) 146 return self._opener.read(self.docket.data_filename())
129 147
130 def write_v2_no_append(self, tr, st, meta, packed): 148 def write_v2_no_append(self, tr, st, meta, packed):
131 old_docket = self.docket 149 old_docket = self.docket
132 new_docket = docketmod.DirstateDocket.with_new_uuid( 150 new_docket = docketmod.DirstateDocket.with_new_uuid(