mirror of
https://github.com/facebook/sapling.git
synced 2024-10-10 16:57:49 +03:00
f4f96c1100
Summary: This introduces a new binary and library that (microwave: it makes warmup faster..!) that can be used to accelerate cache warmup. The idea is the microwave binary will run cache warmup and capture things that are loaded during cache warmup, and commit those to a file. We can then use that file when starting up a host to get a head start on cache warmup by injecting all those entries into our local cache before actually starting cache warmup. Currently, this only supports filenodes, but that's already a pretty good improvement. Changesets should be easy to add as well. Blobs might require a bit more work. Reviewed By: StanislavGlebik Differential Revision: D20219905 fbshipit-source-id: 82bb13ca487f82ca53b4a68a90ac5893895a96e9
117 lines
2.9 KiB
Rust
117 lines
2.9 KiB
Rust
/*
|
|
* 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::Error;
|
|
use cloned::cloned;
|
|
use context::CoreContext;
|
|
use filenodes::{FilenodeInfo, Filenodes, PreparedFilenode};
|
|
use futures::{
|
|
channel::mpsc::Sender,
|
|
compat::Future01CompatExt,
|
|
future::{FutureExt as _, TryFutureExt},
|
|
sink::SinkExt,
|
|
};
|
|
use futures_ext::{BoxFuture, FutureExt};
|
|
use mercurial_types::HgFileNodeId;
|
|
use mononoke_types::{RepoPath, RepositoryId};
|
|
use std::sync::Arc;
|
|
|
|
#[derive(Clone)]
|
|
pub struct MicrowaveFilenodes {
|
|
repo_id: RepositoryId,
|
|
recorder: Sender<PreparedFilenode>,
|
|
inner: Arc<dyn Filenodes>,
|
|
}
|
|
|
|
impl MicrowaveFilenodes {
|
|
pub fn new(
|
|
repo_id: RepositoryId,
|
|
recorder: Sender<PreparedFilenode>,
|
|
inner: Arc<dyn Filenodes>,
|
|
) -> Self {
|
|
Self {
|
|
repo_id,
|
|
recorder,
|
|
inner,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Filenodes for MicrowaveFilenodes {
|
|
fn add_filenodes(
|
|
&self,
|
|
ctx: CoreContext,
|
|
info: Vec<PreparedFilenode>,
|
|
repo_id: RepositoryId,
|
|
) -> BoxFuture<(), Error> {
|
|
self.inner.add_filenodes(ctx, info, repo_id)
|
|
}
|
|
|
|
fn add_or_replace_filenodes(
|
|
&self,
|
|
ctx: CoreContext,
|
|
info: Vec<PreparedFilenode>,
|
|
repo_id: RepositoryId,
|
|
) -> BoxFuture<(), Error> {
|
|
self.inner.add_or_replace_filenodes(ctx, info, repo_id)
|
|
}
|
|
|
|
fn get_filenode(
|
|
&self,
|
|
ctx: CoreContext,
|
|
path: &RepoPath,
|
|
filenode_id: HgFileNodeId,
|
|
repo_id: RepositoryId,
|
|
) -> BoxFuture<Option<FilenodeInfo>, Error> {
|
|
cloned!(self.inner, mut self.recorder, path);
|
|
|
|
// NOTE: Receiving any other repo_id here would be a programming error, so we block it.
|
|
// This wouldn't be on the path of any live traffic, so panicking if this assertion is
|
|
// violated is reasonable.
|
|
assert_eq!(repo_id, self.repo_id);
|
|
|
|
async move {
|
|
let info = inner
|
|
.get_filenode(ctx, &path, filenode_id, repo_id)
|
|
.compat()
|
|
.await?;
|
|
|
|
if let Some(ref info) = info {
|
|
recorder
|
|
.send(PreparedFilenode {
|
|
path,
|
|
info: info.clone(),
|
|
})
|
|
.await?;
|
|
}
|
|
|
|
Ok(info)
|
|
}
|
|
.boxed()
|
|
.compat()
|
|
.boxify()
|
|
}
|
|
|
|
fn get_all_filenodes_maybe_stale(
|
|
&self,
|
|
ctx: CoreContext,
|
|
path: &RepoPath,
|
|
repo_id: RepositoryId,
|
|
) -> BoxFuture<Vec<FilenodeInfo>, Error> {
|
|
self.inner.get_all_filenodes_maybe_stale(ctx, path, repo_id)
|
|
}
|
|
|
|
fn prime_cache(
|
|
&self,
|
|
ctx: &CoreContext,
|
|
repo_id: RepositoryId,
|
|
filenodes: &[PreparedFilenode],
|
|
) {
|
|
self.inner.prime_cache(ctx, repo_id, filenodes)
|
|
}
|
|
}
|