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):
|
def _fetch_tree_impl(self, path, manifest_node):
|
||||||
# type: (str, bytes) -> None
|
# 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])
|
mfnodes = set([manifest_node])
|
||||||
depth = str(self._treefetchdepth)
|
depth = str(self._treefetchdepth)
|
||||||
with self.repo.ui.configoverride(
|
with self.repo.ui.configoverride(
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
import __future__
|
import __future__
|
||||||
|
|
||||||
import __builtin__
|
import __builtin__
|
||||||
|
import _weakref
|
||||||
import contextlib
|
import contextlib
|
||||||
from typing import (
|
from typing import (
|
||||||
Any,
|
Any,
|
||||||
@ -26,7 +27,6 @@ from typing import (
|
|||||||
Union,
|
Union,
|
||||||
)
|
)
|
||||||
|
|
||||||
import _weakref
|
|
||||||
import edenscm.mercurial.connectionpool
|
import edenscm.mercurial.connectionpool
|
||||||
import edenscm.mercurial.context
|
import edenscm.mercurial.context
|
||||||
import edenscm.mercurial.filelog
|
import edenscm.mercurial.filelog
|
||||||
@ -179,6 +179,7 @@ class localrepository(object):
|
|||||||
def _filter(self, filterpats, filename, data) -> Any: ...
|
def _filter(self, filterpats, filename, data) -> Any: ...
|
||||||
def _getsvfsward(self, origfunc) -> Callable: ...
|
def _getsvfsward(self, origfunc) -> Callable: ...
|
||||||
def _getvfsward(self, origfunc) -> Callable: ...
|
def _getvfsward(self, origfunc) -> Callable: ...
|
||||||
|
def _httpgetdesignatednodes(self, keys: Iterable[(str, bytes)]): ...
|
||||||
def _journalfiles(
|
def _journalfiles(
|
||||||
self,
|
self,
|
||||||
) -> Tuple[
|
) -> Tuple[
|
||||||
@ -215,6 +216,7 @@ class localrepository(object):
|
|||||||
def _refreshfilecachestats(repo: localrepository, *args, **kwargs) -> None: ...
|
def _refreshfilecachestats(repo: localrepository, *args, **kwargs) -> None: ...
|
||||||
def _restrictcapabilities(self, caps: Set[str]) -> Set[str]: ...
|
def _restrictcapabilities(self, caps: Set[str]) -> Set[str]: ...
|
||||||
def _rollback(repo: localrepository, *args, **kwargs) -> int: ...
|
def _rollback(repo: localrepository, *args, **kwargs) -> int: ...
|
||||||
|
def _shouldusehttp(self) -> bool: ...
|
||||||
def _syncrevlogtozstore(self) -> None: ...
|
def _syncrevlogtozstore(self) -> None: ...
|
||||||
def _wlockchecktransaction(self) -> None: ...
|
def _wlockchecktransaction(self) -> None: ...
|
||||||
def _writejournal(repo: localrepository, *args, **kwargs) -> None: ...
|
def _writejournal(repo: localrepository, *args, **kwargs) -> None: ...
|
||||||
|
Loading…
Reference in New Issue
Block a user