There's currently no defined order in which Mercurial should open files in the .hg directory. For instance, it's possible to read the changelog first, then several seconds later read the bookmark file. If during those several seconds the repo receives new commits and a bookmark moves, then it will read a bookmark that points at a node that doesn't exist in the inmemory changelog.

We're seeing this on our server, which causes certain bookmarks to disappear for users in some situations (until they pull again).

Has anyone thought about how to solve this? I know we talked about a better storage model that allowed for more snapshot views of the store, but that seems farther off.

I've been thinking about two possible ideas:

1. Introduce a store accessor class that all reads go through. An instance of it would live on the localrepo and it is responsible for providing a snapshotted view of the store. It would contain all the inmemory instances of store structures (the revlogs, the bookmark store, etc). All reads of those structures would go through that class, and it would be responsible for invalidation (like @storecache) and loading them in the right order (so reading the changelog would force the bookmarks to be read first).

This might also be useful for letting other classes hold a reference to the store without holding a reference to the repo. For instance, changectx and manifestctx could hold a reference to the store accessor (since they need access to the changelog and manifest revlogs for reads), instead of the repo (which is a source of circular dependencies).

Having the store be separate from the repo instance could also be useful for having multiple store snapshots inmemory at once. I'm not sure why we would want to, but we could diff the originally loaded store state with a future store state by instantiating two.

2. The option above would be a pretty significant change. Alternatively, I was think about teaching the opener class about the concept of dependencies. We could tell it ".hg/bookmark" should always be opened before ".hg/store/00changelog.i". Then, if anyone tries to read .hg/store/00changelog.i, we will automatically open .hg/bookmark first, if it hasn't already been opened. Then when the bookmark reader comes along, we hand it the already opened file handle.

It's somewhat weird to do it at the opener level, but it would mean we could avoid refactoring the rest of the code base.


Thoughts? Better ideas?

Durham

_______________________________________________
Mercurial-devel mailing list
Mercurial-devel@mercurial-scm.org
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

Reply via email to