Skip to content
Snippets Groups Projects
Commit 8b6fdf35 authored by Georges Racinet's avatar Georges Racinet
Browse files

RHGitaly: repository loading helper for unary RPC methods

This is in particular useful because it makes the return type of
the `spawn_blocking` call explicit, a hint that the compiler would
request even for so simple a method as `FindCommit`.

Like `load_repo_and_stream()` it takes care of converting some errors
into the proper `Status`, still letting the caller define what happens
with `RepoSpecError`, which may have to differ from one request to the other.
parent 12caab4c
No related branches found
No related tags found
2 merge requests!169Protocol v15.9 and stable branch merge",!164RHGitaly CommitService.FindCommit implementation
......@@ -146,6 +146,36 @@
Ok(Response::new(ReceiverStream::new(rx)))
}
/// Load a repository in a separate thread and hand it over to a closure
///
/// This creates a new thread suitable for blocking operations, using
/// [`tokio::task::spawn_blocking`] and then hands it over together with the orignal request
/// to the `and_then` closure, whose return value is finally returned to the caller.
/// The closure is at liberty to use any blocking operation (most calls to `hg-core` are blocking).
///
/// If the repository loading fails, the appropriate gRPC error [`Status`] is returned
///
/// `repo_spec_error_status` plays the same role as in [`load_repo_and_stream`], and again
/// the [`default_repo_spec_error_status`] function can be used in the majority of
/// cases.
pub async fn load_repo_and_then<Req: RequestWithRepo, Res: Send + 'static>(
config: Arc<Config>,
request: Req,
repo_spec_error_status: impl Fn(RepoSpecError) -> Status + Send + 'static,
and_then: impl FnOnce(Req, Repo) -> Result<Res, Status> + Send + 'static,
) -> Result<Res, Status> {
tokio::task::spawn_blocking(move || match load_repo(&config, request.repository_ref()) {
Err(RepoLoadError::SpecError(e)) => Err(repo_spec_error_status(e)),
Err(RepoLoadError::LoadError(e)) => Err(Status::internal(format!(
"Error loading repository: {:?}",
e
))),
Ok(repo) => and_then(request, repo),
})
.await
.map_err(|e| Status::internal(format!("Unexpected error in inner thread: {:?}", e)))?
}
#[cfg(test)]
mod tests {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment