mirror of
https://github.com/facebook/sapling.git
synced 2024-10-05 14:28:17 +03:00
introduce EdenApiContext object
Summary: I want to enable EdenApiHandlers to fetch other repo objects, but that requires various other objects not currently available. I don't want to complicate the handler signature with multiple additional args, so introduce a context object that can contain the dependent objects (i.e. RequestContext and ServerContext). I tucked the path and query extractors into the context since they are barely used by any handlers (in fact, the path extractor is not used at all). Reviewed By: markbt Differential Revision: D45019176 fbshipit-source-id: ec4427d2f134277e89a8c48018f29c5f56cdc60d
This commit is contained in:
parent
4556b1d1f9
commit
d1f0dab4de
@ -27,6 +27,7 @@ use mononoke_api::CompatBlame;
|
||||
use mononoke_api_hg::HgRepoContext;
|
||||
use mononoke_types::blame_v2::BlameV2;
|
||||
|
||||
use super::handler::EdenApiContext;
|
||||
use super::EdenApiHandler;
|
||||
use super::EdenApiMethod;
|
||||
use super::HandlerResult;
|
||||
@ -53,11 +54,10 @@ impl EdenApiHandler for BlameHandler {
|
||||
}
|
||||
|
||||
async fn handler(
|
||||
repo: HgRepoContext,
|
||||
_path: Self::PathExtractor,
|
||||
_query: Self::QueryStringExtractor,
|
||||
ectx: EdenApiContext<Self::PathExtractor, Self::QueryStringExtractor>,
|
||||
request: Self::Request,
|
||||
) -> HandlerResult<'async_trait, Self::Response> {
|
||||
let repo = ectx.repo();
|
||||
let blames = request
|
||||
.files
|
||||
.into_iter()
|
||||
|
@ -23,6 +23,7 @@ use mercurial_types::HgChangesetId;
|
||||
use mercurial_types::HgNodeHash;
|
||||
use mononoke_api_hg::HgRepoContext;
|
||||
|
||||
use super::handler::EdenApiContext;
|
||||
use super::EdenApiHandler;
|
||||
use super::EdenApiMethod;
|
||||
use super::HandlerResult;
|
||||
@ -44,11 +45,10 @@ impl EdenApiHandler for BookmarksHandler {
|
||||
const ENDPOINT: &'static str = "/bookmarks";
|
||||
|
||||
async fn handler(
|
||||
repo: HgRepoContext,
|
||||
_path: Self::PathExtractor,
|
||||
_query: Self::QueryStringExtractor,
|
||||
ectx: EdenApiContext<Self::PathExtractor, Self::QueryStringExtractor>,
|
||||
request: Self::Request,
|
||||
) -> HandlerResult<'async_trait, Self::Response> {
|
||||
let repo = ectx.repo();
|
||||
let fetches = request
|
||||
.bookmarks
|
||||
.into_iter()
|
||||
@ -83,13 +83,11 @@ impl EdenApiHandler for SetBookmarkHandler {
|
||||
const ENDPOINT: &'static str = "/bookmarks/set";
|
||||
|
||||
async fn handler(
|
||||
repo: HgRepoContext,
|
||||
_path: Self::PathExtractor,
|
||||
_query: Self::QueryStringExtractor,
|
||||
ectx: EdenApiContext<Self::PathExtractor, Self::QueryStringExtractor>,
|
||||
request: Self::Request,
|
||||
) -> HandlerResult<'async_trait, Self::Response> {
|
||||
Ok(stream::once(set_bookmark(
|
||||
repo,
|
||||
ectx.repo(),
|
||||
request.bookmark,
|
||||
request.to,
|
||||
request.from,
|
||||
|
@ -72,6 +72,7 @@ use tunables::tunables;
|
||||
use types::HgId;
|
||||
use types::Parents;
|
||||
|
||||
use super::handler::EdenApiContext;
|
||||
use super::EdenApiHandler;
|
||||
use super::EdenApiMethod;
|
||||
use super::HandlerInfo;
|
||||
@ -143,11 +144,10 @@ impl EdenApiHandler for LocationToHashHandler {
|
||||
}
|
||||
|
||||
async fn handler(
|
||||
repo: HgRepoContext,
|
||||
_path: Self::PathExtractor,
|
||||
_query: Self::QueryStringExtractor,
|
||||
ectx: EdenApiContext<Self::PathExtractor, Self::QueryStringExtractor>,
|
||||
request: Self::Request,
|
||||
) -> HandlerResult<'async_trait, Self::Response> {
|
||||
let repo = ectx.repo();
|
||||
let hgid_list = request
|
||||
.requests
|
||||
.into_iter()
|
||||
@ -274,11 +274,10 @@ impl EdenApiHandler for HashLookupHandler {
|
||||
const ENDPOINT: &'static str = "/commit/hash_lookup";
|
||||
|
||||
async fn handler(
|
||||
repo: HgRepoContext,
|
||||
_path: Self::PathExtractor,
|
||||
_query: Self::QueryStringExtractor,
|
||||
ectx: EdenApiContext<Self::PathExtractor, Self::QueryStringExtractor>,
|
||||
request: Self::Request,
|
||||
) -> HandlerResult<'async_trait, Self::Response> {
|
||||
let repo = ectx.repo();
|
||||
use CommitHashLookupRequest::*;
|
||||
Ok(stream::iter(request.batch.into_iter())
|
||||
.then(move |request| {
|
||||
@ -311,11 +310,10 @@ impl EdenApiHandler for UploadHgChangesetsHandler {
|
||||
const ENDPOINT: &'static str = "/upload/changesets";
|
||||
|
||||
async fn handler(
|
||||
repo: HgRepoContext,
|
||||
_path: Self::PathExtractor,
|
||||
_query: Self::QueryStringExtractor,
|
||||
ectx: EdenApiContext<Self::PathExtractor, Self::QueryStringExtractor>,
|
||||
request: Self::Request,
|
||||
) -> HandlerResult<'async_trait, Self::Response> {
|
||||
let repo = ectx.repo();
|
||||
let changesets = request.changesets;
|
||||
let mutations = request.mutations;
|
||||
let changesets_data = changesets
|
||||
@ -365,11 +363,11 @@ impl EdenApiHandler for UploadBonsaiChangesetHandler {
|
||||
const ENDPOINT: &'static str = "/upload/changeset/bonsai";
|
||||
|
||||
async fn handler(
|
||||
repo: HgRepoContext,
|
||||
_path: Self::PathExtractor,
|
||||
query: Self::QueryStringExtractor,
|
||||
ectx: EdenApiContext<Self::PathExtractor, Self::QueryStringExtractor>,
|
||||
request: Self::Request,
|
||||
) -> HandlerResult<'async_trait, Self::Response> {
|
||||
let repo = ectx.repo();
|
||||
let query = ectx.query();
|
||||
let bubble_id = query.bubble_id.map(BubbleId::new);
|
||||
let cs = request.changeset;
|
||||
let repo = &repo;
|
||||
@ -438,12 +436,10 @@ impl EdenApiHandler for FetchSnapshotHandler {
|
||||
const ENDPOINT: &'static str = "/snapshot";
|
||||
|
||||
async fn handler(
|
||||
repo: HgRepoContext,
|
||||
_path: Self::PathExtractor,
|
||||
_query: Self::QueryStringExtractor,
|
||||
ectx: EdenApiContext<Self::PathExtractor, Self::QueryStringExtractor>,
|
||||
request: Self::Request,
|
||||
) -> HandlerResult<'async_trait, Self::Response> {
|
||||
let repo = &repo;
|
||||
let repo = ectx.repo();
|
||||
let cs_id = ChangesetId::from(request.cs_id);
|
||||
let bubble_id = repo
|
||||
.ephemeral_store()
|
||||
@ -526,12 +522,10 @@ impl EdenApiHandler for AlterSnapshotHandler {
|
||||
const ENDPOINT: &'static str = "/snapshot/alter";
|
||||
|
||||
async fn handler(
|
||||
repo: HgRepoContext,
|
||||
_path: Self::PathExtractor,
|
||||
_query: Self::QueryStringExtractor,
|
||||
ectx: EdenApiContext<Self::PathExtractor, Self::QueryStringExtractor>,
|
||||
request: Self::Request,
|
||||
) -> HandlerResult<'async_trait, Self::Response> {
|
||||
let repo = &repo;
|
||||
let repo = ectx.repo();
|
||||
let cs_id = ChangesetId::from(request.cs_id);
|
||||
let id = repo
|
||||
.ephemeral_store()
|
||||
@ -578,11 +572,10 @@ impl EdenApiHandler for EphemeralPrepareHandler {
|
||||
const ENDPOINT: &'static str = "/ephemeral/prepare";
|
||||
|
||||
async fn handler(
|
||||
repo: HgRepoContext,
|
||||
_path: Self::PathExtractor,
|
||||
_query: Self::QueryStringExtractor,
|
||||
ectx: EdenApiContext<Self::PathExtractor, Self::QueryStringExtractor>,
|
||||
request: Self::Request,
|
||||
) -> HandlerResult<'async_trait, Self::Response> {
|
||||
let repo = ectx.repo();
|
||||
Ok(stream::once(async move {
|
||||
Ok(EphemeralPrepareResponse {
|
||||
bubble_id: repo
|
||||
@ -611,11 +604,10 @@ impl EdenApiHandler for GraphHandlerV2 {
|
||||
const ENDPOINT: &'static str = "/commit/graph_v2";
|
||||
|
||||
async fn handler(
|
||||
repo: HgRepoContext,
|
||||
_path: Self::PathExtractor,
|
||||
_query: Self::QueryStringExtractor,
|
||||
ectx: EdenApiContext<Self::PathExtractor, Self::QueryStringExtractor>,
|
||||
request: Self::Request,
|
||||
) -> HandlerResult<'async_trait, Self::Response> {
|
||||
let repo = ectx.repo();
|
||||
let heads = request
|
||||
.heads
|
||||
.into_iter()
|
||||
@ -657,11 +649,10 @@ impl EdenApiHandler for CommitMutationsHandler {
|
||||
const ENDPOINT: &'static str = "/commit/mutations";
|
||||
|
||||
async fn handler(
|
||||
repo: HgRepoContext,
|
||||
_path: Self::PathExtractor,
|
||||
_query: Self::QueryStringExtractor,
|
||||
ectx: EdenApiContext<Self::PathExtractor, Self::QueryStringExtractor>,
|
||||
request: Self::Request,
|
||||
) -> HandlerResult<'async_trait, Self::Response> {
|
||||
let repo = ectx.repo();
|
||||
if !tunables().mutation_generate_for_draft().unwrap_or_default() {
|
||||
return Ok(stream::empty().boxed());
|
||||
}
|
||||
@ -697,11 +688,11 @@ impl EdenApiHandler for CommitTranslateId {
|
||||
const ENDPOINT: &'static str = "/commit/translate_id";
|
||||
|
||||
async fn handler(
|
||||
repo: HgRepoContext,
|
||||
_path: Self::PathExtractor,
|
||||
_query: Self::QueryStringExtractor,
|
||||
ectx: EdenApiContext<Self::PathExtractor, Self::QueryStringExtractor>,
|
||||
request: Self::Request,
|
||||
) -> HandlerResult<'async_trait, Self::Response> {
|
||||
let repo = ectx.repo();
|
||||
|
||||
let mut hg_ids = Vec::new();
|
||||
let mut bonsai_ids = Vec::new();
|
||||
let mut git_ids = Vec::new();
|
||||
|
@ -52,6 +52,7 @@ use rate_limiting::Metric;
|
||||
use serde::Deserialize;
|
||||
use types::Key;
|
||||
|
||||
use super::handler::EdenApiContext;
|
||||
use super::EdenApiHandler;
|
||||
use super::EdenApiMethod;
|
||||
use super::HandlerInfo;
|
||||
@ -102,11 +103,10 @@ impl EdenApiHandler for FilesHandler {
|
||||
}
|
||||
|
||||
async fn handler(
|
||||
repo: HgRepoContext,
|
||||
_path: Self::PathExtractor,
|
||||
_query: Self::QueryStringExtractor,
|
||||
ectx: EdenApiContext<Self::PathExtractor, Self::QueryStringExtractor>,
|
||||
request: Self::Request,
|
||||
) -> HandlerResult<'async_trait, Self::Response> {
|
||||
let repo = ectx.repo();
|
||||
let ctx = repo.ctx().clone();
|
||||
|
||||
let len = request.keys.len() + request.reqs.len();
|
||||
@ -151,11 +151,10 @@ impl EdenApiHandler for Files2Handler {
|
||||
}
|
||||
|
||||
async fn handler(
|
||||
repo: HgRepoContext,
|
||||
_path: Self::PathExtractor,
|
||||
_query: Self::QueryStringExtractor,
|
||||
ectx: EdenApiContext<Self::PathExtractor, Self::QueryStringExtractor>,
|
||||
request: Self::Request,
|
||||
) -> HandlerResult<'async_trait, Self::Response> {
|
||||
let repo = ectx.repo();
|
||||
let ctx = repo.ctx().clone();
|
||||
|
||||
let len = request.keys.len() + request.reqs.len();
|
||||
@ -387,11 +386,10 @@ impl EdenApiHandler for UploadHgFilenodesHandler {
|
||||
const ENDPOINT: &'static str = "/upload/filenodes";
|
||||
|
||||
async fn handler(
|
||||
repo: HgRepoContext,
|
||||
_path: Self::PathExtractor,
|
||||
_query: Self::QueryStringExtractor,
|
||||
ectx: EdenApiContext<Self::PathExtractor, Self::QueryStringExtractor>,
|
||||
request: Self::Request,
|
||||
) -> HandlerResult<'async_trait, Self::Response> {
|
||||
let repo = ectx.repo();
|
||||
let tokens = request
|
||||
.batch
|
||||
.into_iter()
|
||||
@ -415,11 +413,10 @@ impl EdenApiHandler for DownloadFileHandler {
|
||||
const ENDPOINT: &'static str = "/download/file";
|
||||
|
||||
async fn handler(
|
||||
repo: HgRepoContext,
|
||||
_path: Self::PathExtractor,
|
||||
_query: Self::QueryStringExtractor,
|
||||
ectx: EdenApiContext<Self::PathExtractor, Self::QueryStringExtractor>,
|
||||
request: Self::Request,
|
||||
) -> HandlerResult<'async_trait, Self::Response> {
|
||||
let repo = ectx.repo();
|
||||
let content = repo
|
||||
.download_file(request)
|
||||
.await?
|
||||
|
@ -53,6 +53,30 @@ where
|
||||
pub type HandlerResult<'a, Response> =
|
||||
Result<BoxStream<'a, anyhow::Result<Response>>, HandlerError>;
|
||||
|
||||
pub struct EdenApiContext<P, Q> {
|
||||
repo: HgRepoContext,
|
||||
path: P,
|
||||
query: Q,
|
||||
}
|
||||
|
||||
impl<P, Q> EdenApiContext<P, Q> {
|
||||
pub fn new(repo: HgRepoContext, path: P, query: Q) -> Self {
|
||||
Self { repo, path, query }
|
||||
}
|
||||
pub fn repo(&self) -> HgRepoContext {
|
||||
self.repo.clone()
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn path(&self) -> &P {
|
||||
&self.path
|
||||
}
|
||||
|
||||
pub fn query(&self) -> &Q {
|
||||
&self.query
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait EdenApiHandler: 'static {
|
||||
type PathExtractor: PathExtractorWithRepo = BasicPathExtractor;
|
||||
@ -72,9 +96,7 @@ pub trait EdenApiHandler: 'static {
|
||||
}
|
||||
|
||||
async fn handler(
|
||||
repo: HgRepoContext,
|
||||
path: Self::PathExtractor,
|
||||
query: Self::QueryStringExtractor,
|
||||
ctx: EdenApiContext<Self::PathExtractor, Self::QueryStringExtractor>,
|
||||
request: Self::Request,
|
||||
) -> HandlerResult<'async_trait, Self::Response>;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ use mercurial_types::HgNodeHash;
|
||||
use mononoke_api_hg::HgRepoContext;
|
||||
use types::Key;
|
||||
|
||||
use super::handler::EdenApiContext;
|
||||
use super::EdenApiHandler;
|
||||
use super::EdenApiMethod;
|
||||
use super::HandlerResult;
|
||||
@ -44,11 +45,10 @@ impl EdenApiHandler for HistoryHandler {
|
||||
const ENDPOINT: &'static str = "/history";
|
||||
|
||||
async fn handler(
|
||||
repo: HgRepoContext,
|
||||
_path: Self::PathExtractor,
|
||||
_query: Self::QueryStringExtractor,
|
||||
ectx: EdenApiContext<Self::PathExtractor, Self::QueryStringExtractor>,
|
||||
request: Self::Request,
|
||||
) -> HandlerResult<'async_trait, Self::Response> {
|
||||
let repo = ectx.repo();
|
||||
let HistoryRequest { keys, length } = request;
|
||||
|
||||
let fetches = keys.into_iter().map(move |key| {
|
||||
|
@ -22,6 +22,7 @@ use mercurial_types::HgChangesetId;
|
||||
use mercurial_types::HgNodeHash;
|
||||
use mononoke_api_hg::HgRepoContext;
|
||||
|
||||
use super::handler::EdenApiContext;
|
||||
use super::EdenApiHandler;
|
||||
use super::EdenApiMethod;
|
||||
use super::HandlerResult;
|
||||
@ -40,13 +41,11 @@ impl EdenApiHandler for LandStackHandler {
|
||||
const ENDPOINT: &'static str = "/land";
|
||||
|
||||
async fn handler(
|
||||
repo: HgRepoContext,
|
||||
_path: Self::PathExtractor,
|
||||
_query: Self::QueryStringExtractor,
|
||||
ectx: EdenApiContext<Self::PathExtractor, Self::QueryStringExtractor>,
|
||||
request: Self::Request,
|
||||
) -> HandlerResult<'async_trait, Self::Response> {
|
||||
Ok(stream::once(land_stack(
|
||||
repo,
|
||||
ectx.repo(),
|
||||
request.bookmark,
|
||||
request.head,
|
||||
request.base,
|
||||
|
@ -32,6 +32,7 @@ use mononoke_api_hg::HgRepoContext;
|
||||
use repo_blobstore::RepoBlobstoreRef;
|
||||
use repo_identity::RepoIdentityRef;
|
||||
|
||||
use super::handler::EdenApiContext;
|
||||
use super::EdenApiHandler;
|
||||
use super::EdenApiMethod;
|
||||
use super::HandlerResult;
|
||||
@ -211,11 +212,10 @@ impl EdenApiHandler for LookupHandler {
|
||||
const ENDPOINT: &'static str = "/lookup";
|
||||
|
||||
async fn handler(
|
||||
repo: HgRepoContext,
|
||||
_path: Self::PathExtractor,
|
||||
_query: Self::QueryStringExtractor,
|
||||
ectx: EdenApiContext<Self::PathExtractor, Self::QueryStringExtractor>,
|
||||
request: Self::Request,
|
||||
) -> HandlerResult<'async_trait, Self::Response> {
|
||||
let repo = ectx.repo();
|
||||
let tokens = request
|
||||
.batch
|
||||
.into_iter()
|
||||
|
@ -81,6 +81,8 @@ pub(crate) use handler::HandlerError;
|
||||
pub(crate) use handler::HandlerResult;
|
||||
pub(crate) use handler::PathExtractorWithRepo;
|
||||
|
||||
use self::handler::EdenApiContext;
|
||||
|
||||
/// Enum identifying the EdenAPI method that each handler corresponds to.
|
||||
/// Used to identify the handler for logging and stats collection.
|
||||
#[derive(Copy, Clone)]
|
||||
@ -271,7 +273,7 @@ where
|
||||
{
|
||||
let (future_stats, res) = async {
|
||||
let path = Handler::PathExtractor::take_from(&mut state);
|
||||
let query_string = Handler::QueryStringExtractor::take_from(&mut state);
|
||||
let query = Handler::QueryStringExtractor::take_from(&mut state);
|
||||
let content_encoding = ContentEncoding::from_state(&state);
|
||||
|
||||
state.put(HandlerInfo::new(path.repo(), Handler::API_METHOD));
|
||||
@ -289,9 +291,11 @@ where
|
||||
|
||||
if let Some(rd) = RequestDumper::try_borrow_mut_from(&mut state) {
|
||||
rd.add_request(&request);
|
||||
};
|
||||
}
|
||||
|
||||
match Handler::handler(repo, path, query_string, request).await {
|
||||
let ectx = EdenApiContext::new(repo, path, query);
|
||||
|
||||
match Handler::handler(ectx, request).await {
|
||||
Ok(responses) => Ok(encode_response_stream(
|
||||
monitor_request(&state, responses),
|
||||
content_encoding,
|
||||
|
@ -50,6 +50,7 @@ use tunables::tunables;
|
||||
use types::Key;
|
||||
use types::RepoPathBuf;
|
||||
|
||||
use super::handler::EdenApiContext;
|
||||
use super::EdenApiHandler;
|
||||
use super::EdenApiMethod;
|
||||
use super::HandlerInfo;
|
||||
@ -247,11 +248,10 @@ impl EdenApiHandler for UploadTreesHandler {
|
||||
const ENDPOINT: &'static str = "/upload/trees";
|
||||
|
||||
async fn handler(
|
||||
repo: HgRepoContext,
|
||||
_path: Self::PathExtractor,
|
||||
_query: Self::QueryStringExtractor,
|
||||
ectx: EdenApiContext<Self::PathExtractor, Self::QueryStringExtractor>,
|
||||
request: Self::Request,
|
||||
) -> HandlerResult<'async_trait, Self::Response> {
|
||||
let repo = ectx.repo();
|
||||
let tokens = request
|
||||
.batch
|
||||
.into_iter()
|
||||
|
Loading…
Reference in New Issue
Block a user