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