mirror of
https://github.com/facebook/sapling.git
synced 2024-10-06 14:58:03 +03:00
eden: make the EdenFS import helper use EdenAPI's /trees endpoint instead of /complete_trees
Summary: The EdenFS import helper's `_fetch_tree_impl` method works by either calling `repo._prefetchtrees` or `repo.prefetchtrees`, both of which are methods from `treemanifest` extension's `treerepository` class. Unfortunately, these methods are lower-level than their names would suggest, and will always perform gettreepack style fetching (see [1]). If HTTP fetching is enabled, this means that EdenFS will always query EdenAPI's `/complete_trees` endpoint instead of `/trees`, which is needlessly expensive given that EdenFS just wants the exact set of trees specified. As a somewhat hacky workaround, this diff just checks whether HTTP fetching is enabled, and if so, directly calls the appropriate HTTP fetch method. This solution isn't ideal; it would be better for the import helper to request the trees from Mercurial's `remotetreestore` instead of via methods from `treerepository`. Unfortunately, with the current structure of Mercurial's storage layer, the `remotetreestore` isn't readily accessible because it gets passed into the Rust API's storage hierarchy upon construction. --- [1]: The various `*prefetchtrees` methods are usually called from Mercurial's `remotetreestore`, which is where the choice of tree fetching strategy is made (i.e., designated nodes vs gettreepack). The `remotetreestore` then calls `*prefetchtrees` for gettreepack-style fetching, or `*getdesignatednodes` for on-demand fetching. As such, a call to `*prefetchtrees` generally implies gettreepack-style fetching. Reviewed By: quark-zju Differential Revision: D26560451 fbshipit-source-id: 2eedf50a6e66fac78df77214b777544eb8049714
This commit is contained in:
parent
2c0b490179
commit
befabb81c0
@ -660,6 +660,22 @@ class HgServer(object):
|
||||
|
||||
def _fetch_tree_impl(self, path, manifest_node):
|
||||
# type: (str, bytes) -> None
|
||||
|
||||
# The _prefetchtrees function called below will *always* perform
|
||||
# gettreepack-style fetching (even if treemanifest.ondemandfetch is
|
||||
# set to True) because the logic that determines the tree fetching
|
||||
# strategy occurs in Mercurial's `remotetreestore` (which is not
|
||||
# readily accessible here because it is passed into Mercurial's Rust
|
||||
# storage API upon construction.
|
||||
#
|
||||
# As a workaround, let's just check if HTTP fetching is enabled, and
|
||||
# if so, just directly call the appropriate treerepository method to
|
||||
# send the request to EdenAPI's `/trees` endpoint (which only returns
|
||||
# the exact set of trees requested, as desired here).
|
||||
if self.repo._shouldusehttp():
|
||||
self.repo._httpgetdesignatednodes([(path, manifest_node)])
|
||||
return
|
||||
|
||||
mfnodes = set([manifest_node])
|
||||
depth = str(self._treefetchdepth)
|
||||
with self.repo.ui.configoverride(
|
||||
|
@ -8,6 +8,7 @@
|
||||
import __future__
|
||||
|
||||
import __builtin__
|
||||
import _weakref
|
||||
import contextlib
|
||||
from typing import (
|
||||
Any,
|
||||
@ -26,7 +27,6 @@ from typing import (
|
||||
Union,
|
||||
)
|
||||
|
||||
import _weakref
|
||||
import edenscm.mercurial.connectionpool
|
||||
import edenscm.mercurial.context
|
||||
import edenscm.mercurial.filelog
|
||||
@ -179,6 +179,7 @@ class localrepository(object):
|
||||
def _filter(self, filterpats, filename, data) -> Any: ...
|
||||
def _getsvfsward(self, origfunc) -> Callable: ...
|
||||
def _getvfsward(self, origfunc) -> Callable: ...
|
||||
def _httpgetdesignatednodes(self, keys: Iterable[(str, bytes)]): ...
|
||||
def _journalfiles(
|
||||
self,
|
||||
) -> Tuple[
|
||||
@ -215,6 +216,7 @@ class localrepository(object):
|
||||
def _refreshfilecachestats(repo: localrepository, *args, **kwargs) -> None: ...
|
||||
def _restrictcapabilities(self, caps: Set[str]) -> Set[str]: ...
|
||||
def _rollback(repo: localrepository, *args, **kwargs) -> int: ...
|
||||
def _shouldusehttp(self) -> bool: ...
|
||||
def _syncrevlogtozstore(self) -> None: ...
|
||||
def _wlockchecktransaction(self) -> None: ...
|
||||
def _writejournal(repo: localrepository, *args, **kwargs) -> None: ...
|
||||
|
Loading…
Reference in New Issue
Block a user