Show More
@@ -1222,55 +1222,6 b' class localrepository(object):' | |||||
1222 | @mixedrepostorecache(('bookmarks', 'plain'), ('bookmarks.current', 'plain'), |
|
1222 | @mixedrepostorecache(('bookmarks', 'plain'), ('bookmarks.current', 'plain'), | |
1223 | ('00changelog.i', '')) |
|
1223 | ('00changelog.i', '')) | |
1224 | def _bookmarks(self): |
|
1224 | def _bookmarks(self): | |
1225 | # Since the multiple files involved in the transaction cannot be |
|
|||
1226 | # written atomically (with current repository format), there is a race |
|
|||
1227 | # condition here. |
|
|||
1228 | # |
|
|||
1229 | # 1) changelog content A is read |
|
|||
1230 | # 2) outside transaction update changelog to content B |
|
|||
1231 | # 3) outside transaction update bookmark file referring to content B |
|
|||
1232 | # 4) bookmarks file content is read and filtered against changelog-A |
|
|||
1233 | # |
|
|||
1234 | # When this happens, bookmarks against nodes missing from A are dropped. |
|
|||
1235 | # |
|
|||
1236 | # Having this happening during read is not great, but it become worse |
|
|||
1237 | # when this happen during write because the bookmarks to the "unknown" |
|
|||
1238 | # nodes will be dropped for good. However, writes happen within locks. |
|
|||
1239 | # This locking makes it possible to have a race free consistent read. |
|
|||
1240 | # For this purpose data read from disc before locking are |
|
|||
1241 | # "invalidated" right after the locks are taken. This invalidations are |
|
|||
1242 | # "light", the `filecache` mechanism keep the data in memory and will |
|
|||
1243 | # reuse them if the underlying files did not changed. Not parsing the |
|
|||
1244 | # same data multiple times helps performances. |
|
|||
1245 | # |
|
|||
1246 | # Unfortunately in the case describe above, the files tracked by the |
|
|||
1247 | # bookmarks file cache might not have changed, but the in-memory |
|
|||
1248 | # content is still "wrong" because we used an older changelog content |
|
|||
1249 | # to process the on-disk data. So after locking, the changelog would be |
|
|||
1250 | # refreshed but `_bookmarks` would be preserved. |
|
|||
1251 | # Adding `00changelog.i` to the list of tracked file is not |
|
|||
1252 | # enough, because at the time we build the content for `_bookmarks` in |
|
|||
1253 | # (4), the changelog file has already diverged from the content used |
|
|||
1254 | # for loading `changelog` in (1) |
|
|||
1255 | # |
|
|||
1256 | # To prevent the issue, we force the changelog to be explicitly |
|
|||
1257 | # reloaded while computing `_bookmarks`. The data race can still happen |
|
|||
1258 | # without the lock (with a narrower window), but it would no longer go |
|
|||
1259 | # undetected during the lock time refresh. |
|
|||
1260 | # |
|
|||
1261 | # The new schedule is as follow |
|
|||
1262 | # |
|
|||
1263 | # 1) filecache logic detect that `_bookmarks` needs to be computed |
|
|||
1264 | # 2) cachestat for `bookmarks` and `changelog` are captured (for book) |
|
|||
1265 | # 3) We force `changelog` filecache to be tested |
|
|||
1266 | # 4) cachestat for `changelog` are captured (for changelog) |
|
|||
1267 | # 5) `_bookmarks` is computed and cached |
|
|||
1268 | # |
|
|||
1269 | # The step in (3) ensure we have a changelog at least as recent as the |
|
|||
1270 | # cache stat computed in (1). As a result at locking time: |
|
|||
1271 | # * if the changelog did not changed since (1) -> we can reuse the data |
|
|||
1272 | # * otherwise -> the bookmarks get refreshed. |
|
|||
1273 | self._refreshchangelog() |
|
|||
1274 | return bookmarks.bmstore(self) |
|
1225 | return bookmarks.bmstore(self) | |
1275 |
|
1226 | |||
1276 | def _refreshchangelog(self): |
|
1227 | def _refreshchangelog(self): |
@@ -200,7 +200,6 b' Check raced push output.' | |||||
200 | $ cat push-output.txt |
|
200 | $ cat push-output.txt | |
201 | pushing to ssh://user@dummy/bookrace-server |
|
201 | pushing to ssh://user@dummy/bookrace-server | |
202 | searching for changes |
|
202 | searching for changes | |
203 | remote has heads on branch 'default' that are not known locally: f26c3b5167d1 |
|
|||
204 | remote: setting raced push up |
|
203 | remote: setting raced push up | |
205 | remote: adding changesets |
|
204 | remote: adding changesets | |
206 | remote: adding manifests |
|
205 | remote: adding manifests | |
@@ -220,7 +219,7 b' Check result of the push.' | |||||
220 | | summary: A1 |
|
219 | | summary: A1 | |
221 | | |
|
220 | | | |
222 | | o changeset: 3:f26c3b5167d1 |
|
221 | | o changeset: 3:f26c3b5167d1 | |
223 | | | bookmark: book-B |
|
222 | | | bookmark: book-B (false !) | |
224 | | | user: test |
|
223 | | | user: test | |
225 | | | date: Thu Jan 01 00:00:00 1970 +0000 |
|
224 | | | date: Thu Jan 01 00:00:00 1970 +0000 | |
226 | | | summary: B1 |
|
225 | | | summary: B1 | |
@@ -243,4 +242,4 b' Check result of the push.' | |||||
243 |
|
242 | |||
244 | $ hg -R bookrace-server book |
|
243 | $ hg -R bookrace-server book | |
245 | book-A 4:9ce3b28c16de |
|
244 | book-A 4:9ce3b28c16de | |
246 | book-B 3:f26c3b5167d1 |
|
245 | book-B 3:f26c3b5167d1 (false !) |
General Comments 0
You need to be logged in to leave comments.
Login now