Add simple request statistics to debug builds
This commit is contained in:
parent
9cc43d0e32
commit
a6873c91f5
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -415,6 +415,7 @@ dependencies = [
|
||||||
"sha2",
|
"sha2",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -14,6 +14,7 @@ serde = { version = "1.0.162", features = ["derive"] }
|
||||||
serde_json = "1.0.96"
|
serde_json = "1.0.96"
|
||||||
sha2 = "0.10.6"
|
sha2 = "0.10.6"
|
||||||
thiserror = "1.0.40"
|
thiserror = "1.0.40"
|
||||||
|
tracing = "0.1.37"
|
||||||
|
|
||||||
[dependencies.tokio]
|
[dependencies.tokio]
|
||||||
version = "1.28.0"
|
version = "1.28.0"
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
//! We expose a high-level API that deals with "files."
|
//! We expose a high-level API that deals with "files."
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use bytes::{Bytes, BytesMut};
|
use bytes::{Bytes, BytesMut};
|
||||||
|
@ -68,7 +70,7 @@ pub enum Error {
|
||||||
TooManyCollisions,
|
TooManyCollisions,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug)]
|
||||||
pub struct Api {
|
pub struct Api {
|
||||||
/// Credentials to access the cache.
|
/// Credentials to access the cache.
|
||||||
credentials: Credentials,
|
credentials: Credentials,
|
||||||
|
@ -84,6 +86,10 @@ pub struct Api {
|
||||||
|
|
||||||
/// The HTTP client for authenticated requests.
|
/// The HTTP client for authenticated requests.
|
||||||
client: Client,
|
client: Client,
|
||||||
|
|
||||||
|
/// Backend request statistics.
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
stats: RequestStats,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A file allocation.
|
/// A file allocation.
|
||||||
|
@ -182,6 +188,14 @@ struct CommitCacheRequest {
|
||||||
size: usize,
|
size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
struct RequestStats {
|
||||||
|
get: AtomicUsize,
|
||||||
|
post: AtomicUsize,
|
||||||
|
patch: AtomicUsize,
|
||||||
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
trait ResponseExt {
|
trait ResponseExt {
|
||||||
async fn check(self) -> Result<()>;
|
async fn check(self) -> Result<()>;
|
||||||
|
@ -240,6 +254,8 @@ impl Api {
|
||||||
version: initial_version,
|
version: initial_version,
|
||||||
version_hasher,
|
version_hasher,
|
||||||
client,
|
client,
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
stats: Default::default(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,6 +327,9 @@ impl Api {
|
||||||
|
|
||||||
let chunk_len = chunk.len();
|
let chunk_len = chunk.len();
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
self.stats.patch.fetch_add(1, Ordering::SeqCst);
|
||||||
|
|
||||||
self.client
|
self.client
|
||||||
.patch(self.construct_url(&format!("caches/{}", allocation.0 .0)))
|
.patch(self.construct_url(&format!("caches/{}", allocation.0 .0)))
|
||||||
.header(CONTENT_TYPE, "application/octet-stream")
|
.header(CONTENT_TYPE, "application/octet-stream")
|
||||||
|
@ -340,10 +359,21 @@ impl Api {
|
||||||
.map(|entry| entry.archive_location))
|
.map(|entry| entry.archive_location))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Dumps statistics.
|
||||||
|
///
|
||||||
|
/// This is for debugging only.
|
||||||
|
pub fn dump_stats(&self) {
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
tracing::debug!("Request stats: {:#?}", self.stats);
|
||||||
|
}
|
||||||
|
|
||||||
// Private
|
// Private
|
||||||
|
|
||||||
/// Retrieves a cache based on a list of key prefixes.
|
/// Retrieves a cache based on a list of key prefixes.
|
||||||
async fn get_cache_entry(&self, keys: &[&str]) -> Result<Option<ArtifactCacheEntry>> {
|
async fn get_cache_entry(&self, keys: &[&str]) -> Result<Option<ArtifactCacheEntry>> {
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
self.stats.get.fetch_add(1, Ordering::SeqCst);
|
||||||
|
|
||||||
let res = self
|
let res = self
|
||||||
.client
|
.client
|
||||||
.get(self.construct_url("cache"))
|
.get(self.construct_url("cache"))
|
||||||
|
@ -376,6 +406,9 @@ impl Api {
|
||||||
cache_size,
|
cache_size,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
self.stats.post.fetch_add(1, Ordering::SeqCst);
|
||||||
|
|
||||||
let res = self
|
let res = self
|
||||||
.client
|
.client
|
||||||
.post(self.construct_url("caches"))
|
.post(self.construct_url("caches"))
|
||||||
|
@ -392,6 +425,9 @@ impl Api {
|
||||||
async fn commit_cache(&self, cache_id: CacheId, size: usize) -> Result<()> {
|
async fn commit_cache(&self, cache_id: CacheId, size: usize) -> Result<()> {
|
||||||
let req = CommitCacheRequest { size };
|
let req = CommitCacheRequest { size };
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
self.stats.post.fetch_add(1, Ordering::SeqCst);
|
||||||
|
|
||||||
self.client
|
self.client
|
||||||
.post(self.construct_url(&format!("caches/{}", cache_id.0)))
|
.post(self.construct_url(&format!("caches/{}", cache_id.0)))
|
||||||
.json(&req)
|
.json(&req)
|
||||||
|
|
|
@ -86,11 +86,14 @@ async fn main() {
|
||||||
.route("/:path", put(put_narinfo))
|
.route("/:path", put(put_narinfo))
|
||||||
// .nar
|
// .nar
|
||||||
.route("/nar/:path", get(get_nar))
|
.route("/nar/:path", get(get_nar))
|
||||||
.route("/nar/:path", put(put_nar))
|
.route("/nar/:path", put(put_nar));
|
||||||
.layer(Extension(state));
|
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
let app = app.layer(tower_http::trace::TraceLayer::new_for_http());
|
let app = app
|
||||||
|
.layer(tower_http::trace::TraceLayer::new_for_http())
|
||||||
|
.layer(axum::middleware::from_fn(dump_api_stats));
|
||||||
|
|
||||||
|
let app = app.layer(Extension(state));
|
||||||
|
|
||||||
tracing::info!("listening on {}", args.listen);
|
tracing::info!("listening on {}", args.listen);
|
||||||
axum::Server::bind(&args.listen)
|
axum::Server::bind(&args.listen)
|
||||||
|
@ -99,6 +102,16 @@ async fn main() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
async fn dump_api_stats<B>(
|
||||||
|
Extension(state): Extension<State>,
|
||||||
|
request: axum::http::Request<B>,
|
||||||
|
next: axum::middleware::Next<B>,
|
||||||
|
) -> axum::response::Response {
|
||||||
|
state.api.dump_stats();
|
||||||
|
next.run(request).await
|
||||||
|
}
|
||||||
|
|
||||||
async fn root() -> &'static str {
|
async fn root() -> &'static str {
|
||||||
"cache the world 🚀"
|
"cache the world 🚀"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue