Mercurial > hg
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( |