mirror of
https://github.com/facebook/sapling.git
synced 2024-10-07 07:17:55 +03:00
bindings: allow choice between edenapi backends
Summary: Allow users to configure which HTTP client backend to use for the Eden API via the `edenapi.backend` config option. Valid options are `curl` and `hyper`, with `curl` being the default. Reviewed By: quark-zju Differential Revision: D14657871 fbshipit-source-id: 7a9972d2380fbbd5ed62d1accae764dc03ca4c29
This commit is contained in:
parent
6c8c87dea1
commit
6705e2d120
@ -124,6 +124,8 @@ Configs for Eden API (HTTP data fetching):
|
||||
|
||||
``edenapi.url`` specifies the base URL of the API server.
|
||||
|
||||
``edenapi.backend`` specifies which HTTP client library to use.
|
||||
|
||||
Eden API TLS credentials are configured using the auth section:
|
||||
|
||||
``auth.edenapi.prefix``: base URL (without scheme) for which to set credentials.
|
||||
@ -218,6 +220,7 @@ configitem("remotefilelog", "server", default=None)
|
||||
# Config items for HTTP data fetching.
|
||||
configitem("edenapi", "enabled", default=False)
|
||||
configitem("edenapi", "url", default=None)
|
||||
configitem("edenapi", "backend", default="curl")
|
||||
|
||||
testedwith = "ships-with-fb-hgext"
|
||||
|
||||
|
@ -47,4 +47,5 @@ def initclient(ui, repo):
|
||||
url = getbaseurl(ui)
|
||||
creds = getcreds(ui, url)
|
||||
cachepath = shallowutil.getcachepath(ui)
|
||||
return edenapi.client(url, cachepath, repo.name, creds)
|
||||
backend = ui.config("edenapi", "backend")
|
||||
return edenapi.client(url, cachepath, repo.name, backend, creds)
|
||||
|
@ -22,6 +22,7 @@ encoding = { path = "../../../../lib/encoding" }
|
||||
env_logger = "0.5.13"
|
||||
failure = "0.1.3"
|
||||
lz4-pyframe = { path = "../../../../lib/lz4-pyframe" }
|
||||
log = "0.4.6"
|
||||
mutationstore = { path = "../../../../lib/mutationstore" }
|
||||
nodemap = { path = "../../../../lib/nodemap" }
|
||||
pathmatcher = { path = "../../../../lib/pathmatcher" }
|
||||
|
@ -7,9 +7,11 @@ use std::str;
|
||||
|
||||
use cpython::*;
|
||||
use cpython_failure::ResultPyErrExt;
|
||||
|
||||
use ::edenapi::{Config, EdenApi, EdenApiHyperClient};
|
||||
use encoding::{local_bytes_to_path, path_to_local_bytes};
|
||||
use failure::format_err;
|
||||
use log;
|
||||
|
||||
use ::edenapi::{Config, EdenApi, EdenApiCurlClient, EdenApiHyperClient};
|
||||
use types::{Key, Node};
|
||||
|
||||
pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
|
||||
@ -20,18 +22,20 @@ pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
|
||||
}
|
||||
|
||||
py_class!(class client |py| {
|
||||
data inner: EdenApiHyperClient;
|
||||
data inner: Box<dyn EdenApi>;
|
||||
|
||||
def __new__(
|
||||
_cls,
|
||||
base_url: &PyBytes,
|
||||
cache_path: &PyBytes,
|
||||
repo: &PyBytes,
|
||||
backend: &PyBytes,
|
||||
client_creds: Option<(&PyBytes, &PyBytes)> = None
|
||||
) -> PyResult<client> {
|
||||
let base_url = str::from_utf8(base_url.data(py)).map_pyerr::<exc::RuntimeError>(py)?;
|
||||
let cache_path = str::from_utf8(cache_path.data(py)).map_pyerr::<exc::RuntimeError>(py)?;
|
||||
let cache_path = local_bytes_to_path(&cache_path.data(py)).map_pyerr::<exc::RuntimeError>(py)?;
|
||||
let repo = str::from_utf8(repo.data(py)).map_pyerr::<exc::RuntimeError>(py)?;
|
||||
let backend = str::from_utf8(backend.data(py)).map_pyerr::<exc::RuntimeError>(py)?;
|
||||
|
||||
let mut config = Config::new()
|
||||
.base_url_str(base_url)
|
||||
@ -45,7 +49,22 @@ py_class!(class client |py| {
|
||||
config = config.client_creds(cert, key);
|
||||
}
|
||||
|
||||
let inner = EdenApiHyperClient::new(config).map_pyerr::<exc::RuntimeError>(py)?;
|
||||
let inner = match backend {
|
||||
"curl" => {
|
||||
log::debug!("Using curl-backed Eden API client");
|
||||
let client = EdenApiCurlClient::new(config).map_pyerr::<exc::RuntimeError>(py)?;
|
||||
Box::new(client) as Box<dyn EdenApi>
|
||||
},
|
||||
"hyper" => {
|
||||
log::debug!("Using hyper-backed Eden API client");
|
||||
let client = EdenApiHyperClient::new(config).map_pyerr::<exc::RuntimeError>(py)?;
|
||||
Box::new(client) as Box<dyn EdenApi>
|
||||
},
|
||||
invalid => {
|
||||
return Err(format_err!("Invalid Eden API backend: {}", invalid)).map_pyerr::<exc::RuntimeError>(py);
|
||||
},
|
||||
};
|
||||
|
||||
client::create_instance(py, inner)
|
||||
}
|
||||
|
||||
|
@ -6,23 +6,25 @@ use failure::Fallible;
|
||||
|
||||
use types::Key;
|
||||
|
||||
pub trait EdenApi {
|
||||
pub trait EdenApi: Send {
|
||||
/// Hit the API server's /health_check endpoint.
|
||||
/// Returns Ok(()) if the expected response is received, or an Error otherwise
|
||||
/// (e.g., if there was a connection problem or an unexpected repsonse).
|
||||
fn health_check(&self) -> Fallible<()>;
|
||||
|
||||
/// Fetch the content of the specified file from the API server and write
|
||||
/// it to a datapack in the configured cache directory. Returns the path
|
||||
/// Fetch the content of the specified files from the API server and write
|
||||
/// them to a datapack in the configured cache directory. Returns the path
|
||||
/// of the resulting packfile.
|
||||
fn get_files(&self, keys: impl IntoIterator<Item = Key>) -> Fallible<PathBuf>;
|
||||
///
|
||||
/// Note that the keys are passed in as a `Vec` rather than using `IntoIterator`
|
||||
/// in order to keep this trait object-safe.
|
||||
fn get_files(&self, keys: Vec<Key>) -> Fallible<PathBuf>;
|
||||
|
||||
/// Fetch the history of the specified file from the API server and write
|
||||
/// it to a historypack in the configured cache directory. Returns the path
|
||||
/// Fetch the history of the specified files from the API server and write
|
||||
/// them to a historypack in the configured cache directory. Returns the path
|
||||
/// of the resulting packfile.
|
||||
fn get_history(
|
||||
&self,
|
||||
keys: impl IntoIterator<Item = Key>,
|
||||
max_depth: Option<u32>,
|
||||
) -> Fallible<PathBuf>;
|
||||
///
|
||||
/// Note that the keys are passed in as a `Vec` rather than using `IntoIterator`
|
||||
/// in order to keep this trait object-safe.
|
||||
fn get_history(&self, keys: Vec<Key>, max_depth: Option<u32>) -> Fallible<PathBuf>;
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ impl EdenApi for EdenApiCurlClient {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_files(&self, keys: impl IntoIterator<Item = Key>) -> Fallible<PathBuf> {
|
||||
fn get_files(&self, keys: Vec<Key>) -> Fallible<PathBuf> {
|
||||
let url = self.repo_base_url()?.join(paths::DATA)?;
|
||||
|
||||
let request = FileDataRequest {
|
||||
@ -124,11 +124,7 @@ impl EdenApi for EdenApiCurlClient {
|
||||
write_datapack(self.pack_cache_path(), response)
|
||||
}
|
||||
|
||||
fn get_history(
|
||||
&self,
|
||||
keys: impl IntoIterator<Item = Key>,
|
||||
max_depth: Option<u32>,
|
||||
) -> Fallible<PathBuf> {
|
||||
fn get_history(&self, keys: Vec<Key>, max_depth: Option<u32>) -> Fallible<PathBuf> {
|
||||
let url = self.repo_base_url()?.join(paths::HISTORY)?;
|
||||
|
||||
let request = FileHistoryRequest {
|
||||
|
@ -126,7 +126,7 @@ impl EdenApi for EdenApiHyperClient {
|
||||
/// Fetch the content of the specified file from the API server and write
|
||||
/// it to a datapack in the configured cache directory. Returns the path
|
||||
/// of the resulting packfile.
|
||||
fn get_files(&self, keys: impl IntoIterator<Item = Key>) -> Fallible<PathBuf> {
|
||||
fn get_files(&self, keys: Vec<Key>) -> Fallible<PathBuf> {
|
||||
let client = Arc::clone(&self.client);
|
||||
let prefix = self.repo_base_url()?.join(paths::GET_FILE)?;
|
||||
|
||||
@ -145,11 +145,7 @@ impl EdenApi for EdenApiHyperClient {
|
||||
/// Fetch the history of the specified file from the API server and write
|
||||
/// it to a historypack in the configured cache directory. Returns the path
|
||||
/// of the resulting packfile.
|
||||
fn get_history(
|
||||
&self,
|
||||
keys: impl IntoIterator<Item = Key>,
|
||||
max_depth: Option<u32>,
|
||||
) -> Fallible<PathBuf> {
|
||||
fn get_history(&self, keys: Vec<Key>, max_depth: Option<u32>) -> Fallible<PathBuf> {
|
||||
let client = Arc::clone(&self.client);
|
||||
let prefix = self.repo_base_url()?.join(paths::GET_HISTORY)?;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user