mirror of
https://github.com/facebook/sapling.git
synced 2024-10-10 08:47:12 +03:00
edenapi_server: add bookmark endpoint
Summary: Add the EdenAPI endpoint for resolving bookmarks. This is a first pass that just takes a bookmark name as a path variable, to make sure that this is on the right track. We'll want to add a proper request type that includes a list of bookmarks and a response type that can indicate that no bookmark was found. Then the hg bookmark command will also need support for prefix listing capabilities. Reviewed By: kulshrax Differential Revision: D26920845 fbshipit-source-id: 067db6a636a75531ee5953392b734c038a58efb6
This commit is contained in:
parent
3525a5b1e3
commit
bd89a4c855
@ -8,6 +8,7 @@ license = "GPLv2+"
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
async-trait = "0.1.45"
|
||||
bookmarks = { version = "0.1.0", path = "../bookmarks" }
|
||||
bytes = { version = "0.5", features = ["serde"] }
|
||||
cloned = { version = "0.1.0", git = "https://github.com/facebookexperimental/rust-shed.git", branch = "master" }
|
||||
context = { version = "0.1.0", path = "../server/context" }
|
||||
|
57
eden/mononoke/edenapi_service/src/handlers/bookmarks.rs
Normal file
57
eden/mononoke/edenapi_service/src/handlers/bookmarks.rs
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This software may be used and distributed according to the terms of the
|
||||
* GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
use anyhow::Context;
|
||||
|
||||
use bookmarks::Freshness;
|
||||
use bytes::Bytes;
|
||||
use gotham::state::{FromState, State};
|
||||
use gotham_derive::{StateData, StaticResponseExtender};
|
||||
use gotham_ext::{error::HttpError, response::BytesBody};
|
||||
use mercurial_types::HgChangesetId;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::context::ServerContext;
|
||||
use crate::errors::ErrorKind;
|
||||
use crate::errors::MononokeErrorExt;
|
||||
use crate::middleware::RequestContext;
|
||||
use crate::utils::get_repo;
|
||||
|
||||
use super::{EdenApiMethod, HandlerInfo};
|
||||
|
||||
/// TODO: add Edenapi and Edenapi::wire type for request and response type
|
||||
/// add support for prefix listing
|
||||
#[derive(Clone, Serialize, Debug)]
|
||||
struct BookmarksResponse {
|
||||
bookmark_value: Option<HgChangesetId>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, StateData, StaticResponseExtender)]
|
||||
pub struct BookmarksParams {
|
||||
repo: String,
|
||||
bookmark: String,
|
||||
}
|
||||
|
||||
pub async fn bookmarks(state: &mut State) -> Result<BytesBody<Bytes>, HttpError> {
|
||||
let params = BookmarksParams::take_from(state);
|
||||
state.put(HandlerInfo::new(¶ms.repo, EdenApiMethod::Bookmarks));
|
||||
let sctx = ServerContext::borrow_from(state);
|
||||
let rctx = RequestContext::borrow_from(state).clone();
|
||||
let repo = get_repo(&sctx, &rctx, ¶ms.repo, None).await?;
|
||||
let bookmark_value = repo
|
||||
.resolve_bookmark(params.bookmark, Freshness::MaybeStale)
|
||||
.await
|
||||
.map_err(|e| e.into_http_error("error resolving bookmark"))?;
|
||||
|
||||
// TODO: add cbor serialization when the response type is changed to an
|
||||
// Edenapi wire type.
|
||||
let bytes: Bytes = serde_json::to_string(&BookmarksResponse { bookmark_value })
|
||||
.context(ErrorKind::SerializationFailed)
|
||||
.map_err(HttpError::e500)?
|
||||
.into();
|
||||
Ok(BytesBody::new(bytes, mime::APPLICATION_JSON))
|
||||
}
|
@ -26,6 +26,7 @@ use gotham_ext::response::build_response;
|
||||
use crate::context::ServerContext;
|
||||
use crate::middleware::RequestContext;
|
||||
|
||||
mod bookmarks;
|
||||
mod clone;
|
||||
mod commit;
|
||||
mod complete_trees;
|
||||
@ -47,6 +48,7 @@ pub enum EdenApiMethod {
|
||||
CommitRevlogData,
|
||||
Clone,
|
||||
FullIdMapClone,
|
||||
Bookmarks,
|
||||
}
|
||||
|
||||
impl fmt::Display for EdenApiMethod {
|
||||
@ -61,6 +63,7 @@ impl fmt::Display for EdenApiMethod {
|
||||
Self::CommitRevlogData => "commit_revlog_data",
|
||||
Self::Clone => "clone",
|
||||
Self::FullIdMapClone => "full_idmap_clone",
|
||||
Self::Bookmarks => "bookmarks",
|
||||
};
|
||||
write!(f, "{}", name)
|
||||
}
|
||||
@ -125,6 +128,7 @@ define_handler!(commit_hash_to_location_handler, commit::hash_to_location);
|
||||
define_handler!(commit_revlog_data_handler, commit::revlog_data);
|
||||
define_handler!(clone_handler, clone::clone_data);
|
||||
define_handler!(full_idmap_clone_handler, clone::full_idmap_clone_data);
|
||||
define_handler!(bookmarks_handler, bookmarks::bookmarks);
|
||||
|
||||
fn health_handler(state: State) -> (State, &'static str) {
|
||||
if ServerContext::borrow_from(&state).will_exit() {
|
||||
@ -177,5 +181,9 @@ pub fn build_router(ctx: ServerContext) -> Router {
|
||||
.post("/:repo/full_idmap_clone")
|
||||
.with_path_extractor::<clone::CloneParams>()
|
||||
.to(full_idmap_clone_handler);
|
||||
route
|
||||
.get("/:repo/bookmarks/:bookmark")
|
||||
.with_path_extractor::<bookmarks::BookmarksParams>()
|
||||
.to(bookmarks_handler);
|
||||
})
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ define_stats! {
|
||||
commit_revlog_data_duration: dynamic_histogram("{}.commit_revlog_data_ms", (repo: String); 10, 0, 500, Average, Sum, Count; P 5; P 25; P 50; P 75; P 95; P 97; P 99),
|
||||
clone_duration: dynamic_histogram("{}.clone_data_ms", (repo: String); 10, 0, 500, Average, Sum, Count; P 5; P 25; P 50; P 75; P 95; P 97; P 99),
|
||||
full_idmap_clone_duration: dynamic_histogram("{}.full_idmap_clone_data_ms", (repo: String); 10, 0, 500, Average, Sum, Count; P 5; P 25; P 50; P 75; P 95; P 97; P 99),
|
||||
bookmarks_duration: dynamic_histogram("{}.full_idmap_clone_data_ms", (repo: String); 10, 0, 500, Average, Sum, Count; P 5; P 25; P 50; P 75; P 95; P 97; P 99),
|
||||
}
|
||||
|
||||
fn log_stats(state: &mut State, status: StatusCode) -> Option<()> {
|
||||
@ -66,6 +67,7 @@ fn log_stats(state: &mut State, status: StatusCode) -> Option<()> {
|
||||
CommitRevlogData => STATS::commit_revlog_data_duration.add_value(dur_ms, (repo,)),
|
||||
Clone => STATS::clone_duration.add_value(dur_ms, (repo,)),
|
||||
FullIdMapClone => STATS::full_idmap_clone_duration.add_value(dur_ms, (repo,)),
|
||||
Bookmarks => STATS::bookmarks_duration.add_value(dur_ms, (repo,)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -841,7 +841,9 @@ impl RepoContext {
|
||||
bookmark: impl AsRef<str>,
|
||||
freshness: BookmarkFreshness,
|
||||
) -> Result<Option<ChangesetContext>, MononokeError> {
|
||||
let bookmark = BookmarkName::new(bookmark.as_ref())?;
|
||||
// a non ascii bookmark name is an invalid request
|
||||
let bookmark = BookmarkName::new(bookmark.as_ref())
|
||||
.map_err(|e| MononokeError::InvalidRequest(e.to_string()))?;
|
||||
|
||||
let mut cs_id = match freshness {
|
||||
BookmarkFreshness::MaybeStale => self.warm_bookmarks_cache().get(&bookmark),
|
||||
|
@ -11,6 +11,7 @@ async-trait = "0.1.45"
|
||||
blobrepo = { version = "0.1.0", path = "../blobrepo" }
|
||||
blobrepo_hg = { version = "0.1.0", path = "../blobrepo/blobrepo_hg" }
|
||||
blobstore = { version = "0.1.0", path = "../blobstore" }
|
||||
bookmarks = { version = "0.1.0", path = "../bookmarks" }
|
||||
bytes = { version = "0.5", features = ["serde"] }
|
||||
context = { version = "0.1.0", path = "../server/context" }
|
||||
filestore = { version = "0.1.0", path = "../filestore" }
|
||||
|
@ -10,6 +10,7 @@ use std::collections::HashMap;
|
||||
use anyhow::{self, format_err, Context};
|
||||
use blobrepo::BlobRepo;
|
||||
use blobrepo_hg::BlobRepoHg;
|
||||
use bookmarks::Freshness;
|
||||
use bytes::Bytes;
|
||||
use context::CoreContext;
|
||||
use futures::compat::Stream01CompatExt;
|
||||
@ -316,6 +317,18 @@ impl HgRepoContext {
|
||||
};
|
||||
Ok(hg_clone_data)
|
||||
}
|
||||
|
||||
/// resolve a bookmark name to an Hg Changeset
|
||||
pub async fn resolve_bookmark(
|
||||
&self,
|
||||
bookmark: impl AsRef<str>,
|
||||
freshness: Freshness,
|
||||
) -> Result<Option<HgChangesetId>, MononokeError> {
|
||||
match self.repo.resolve_bookmark(bookmark, freshness).await? {
|
||||
Some(c) => c.hg_id().await,
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn hg_convert_idmap_chunk(
|
||||
|
Loading…
Reference in New Issue
Block a user