Skip to content

Commit

Permalink
Expose page generation time
Browse files Browse the repository at this point in the history
  • Loading branch information
w4 committed Jan 21, 2024
1 parent d5e06c5 commit a254a4a
Show file tree
Hide file tree
Showing 15 changed files with 126 additions and 76 deletions.
9 changes: 7 additions & 2 deletions src/layers/logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use axum::{
http::{HeaderValue, Method, Request, Response},
};
use futures::future::{Future, FutureExt, Join, Map, Ready};
use tokio::task::futures::TaskLocalFuture;
use tower_service::Service;
use tracing::{error, info, instrument::Instrumented, Instrument, Span};
use uuid::Uuid;
Expand All @@ -37,7 +38,7 @@ where
type Response = S::Response;
type Error = S::Error;
type Future = Map<
Join<Instrumented<S::Future>, Ready<PendingLogMessage>>,
Join<TaskLocalFuture<Instant, Instrumented<S::Future>>, Ready<PendingLogMessage>>,
fn((<S::Future as Future>::Output, PendingLogMessage)) -> <S::Future as Future>::Output,
>;

Expand All @@ -63,7 +64,7 @@ where
};

futures::future::join(
self.0.call(req).instrument(span),
REQ_TIMESTAMP.scope(log_message.start, self.0.call(req).instrument(span)),
futures::future::ready(log_message),
)
.map(|(response, pending_log_message)| {
Expand All @@ -78,6 +79,10 @@ where
}
}

tokio::task_local! {
pub static REQ_TIMESTAMP: Instant;
}

pub struct PendingLogMessage {
span: Span,
request_id: Uuid,
Expand Down
44 changes: 34 additions & 10 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,17 +315,41 @@ pub fn build_asset_hash(v: &[u8]) -> Box<str> {
Box::from(out)
}

#[instrument(skip(t))]
pub fn into_response<T: Template>(t: &T) -> Response {
match t.render() {
Ok(body) => {
let headers = [(
http::header::CONTENT_TYPE,
HeaderValue::from_static(T::MIME_TYPE),
)];
pub struct TemplateResponse<T> {
template: T,
}

impl<T: Template> IntoResponse for TemplateResponse<T> {
#[instrument(skip_all)]
fn into_response(self) -> Response {
match self.template.render() {
Ok(body) => {
let headers = [(
http::header::CONTENT_TYPE,
HeaderValue::from_static(T::MIME_TYPE),
)];

(headers, body).into_response()
}
Err(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
}
}
}

pub fn into_response<T: Template>(template: T) -> impl IntoResponse {
TemplateResponse { template }
}

(headers, body).into_response()
pub enum ResponseEither<A, B> {
Left(A),
Right(B),
}

impl<A: IntoResponse, B: IntoResponse> IntoResponse for ResponseEither<A, B> {
fn into_response(self) -> Response {
match self {
Self::Left(a) => a.into_response(),
Self::Right(b) => b.into_response(),
}
Err(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(),
}
}
7 changes: 7 additions & 0 deletions src/methods/filters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
#![allow(clippy::unnecessary_wraps, clippy::trivially_copy_pass_by_ref)]

use std::borrow::Borrow;
use time::format_description::well_known::Rfc3339;

pub fn format_time(s: time::OffsetDateTime) -> Result<String, askama::Error> {
s.format(&Rfc3339)
.map_err(Box::from)
.map_err(askama::Error::Custom)
}

pub fn timeago(s: impl Borrow<time::OffsetDateTime>) -> Result<String, askama::Error> {
Ok(timeago::Formatter::new()
Expand Down
21 changes: 12 additions & 9 deletions src/methods/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,37 @@ use std::{collections::BTreeMap, sync::Arc};

use anyhow::Context;
use askama::Template;
use axum::{response::Response, Extension};
use axum::{response::IntoResponse, Extension};

use super::filters;
use crate::{database::schema::repository::Repository, into_response};
use crate::{
database::schema::repository::{Repository, YokedRepository},
into_response,
};

#[derive(Template)]
#[template(path = "index.html")]
pub struct View<'a> {
pub repositories: BTreeMap<Option<String>, Vec<&'a Repository<'a>>>,
pub struct View {
pub repositories: BTreeMap<Option<String>, Vec<YokedRepository>>,
}

pub async fn handle(
Extension(db): Extension<Arc<rocksdb::DB>>,
) -> Result<Response, super::repo::Error> {
let mut repositories: BTreeMap<Option<String>, Vec<&Repository<'_>>> = BTreeMap::new();
) -> Result<impl IntoResponse, super::repo::Error> {
let mut repositories: BTreeMap<Option<String>, Vec<YokedRepository>> = BTreeMap::new();

let fetched = tokio::task::spawn_blocking(move || Repository::fetch_all(&db))
.await
.context("Failed to join Tokio task")??;
for (k, v) in &fetched {
for (k, v) in fetched {
// TODO: fixme
let mut split: Vec<_> = k.split('/').collect();
split.pop();
let key = Some(split.join("/")).filter(|v| !v.is_empty());

let k = repositories.entry(key).or_default();
k.push(v.get());
k.push(v);
}

Ok(into_response(&View { repositories }))
Ok(into_response(View { repositories }))
}
11 changes: 7 additions & 4 deletions src/methods/repo/about.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
use std::sync::Arc;

use askama::Template;
use axum::{extract::Query, response::Response, Extension};
use axum::{extract::Query, response::IntoResponse, Extension};
use serde::Deserialize;

use crate::{
git::ReadmeFormat,
into_response,
methods::repo::{Repository, RepositoryPath, Result},
methods::{
filters,
repo::{Repository, RepositoryPath, Result},
},
Git,
};

Expand All @@ -30,14 +33,14 @@ pub async fn handle(
Extension(RepositoryPath(repository_path)): Extension<RepositoryPath>,
Extension(git): Extension<Arc<Git>>,
Query(query): Query<UriQuery>,
) -> Result<Response> {
) -> Result<impl IntoResponse> {
let open_repo = git
.clone()
.repo(repository_path, query.branch.clone())
.await?;
let readme = open_repo.readme().await?;

Ok(into_response(&View {
Ok(into_response(View {
repo,
readme,
branch: query.branch,
Expand Down
11 changes: 7 additions & 4 deletions src/methods/repo/commit.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
use std::sync::Arc;

use askama::Template;
use axum::{extract::Query, response::Response, Extension};
use axum::{extract::Query, response::IntoResponse, Extension};
use serde::Deserialize;

use crate::{
git::Commit,
into_response,
methods::repo::{Repository, RepositoryPath, Result},
methods::{
filters,
repo::{Repository, RepositoryPath, Result},
},
Git,
};

Expand All @@ -33,7 +36,7 @@ pub async fn handle(
Extension(RepositoryPath(repository_path)): Extension<RepositoryPath>,
Extension(git): Extension<Arc<Git>>,
Query(query): Query<UriQuery>,
) -> Result<Response> {
) -> Result<impl IntoResponse> {
let open_repo = git.repo(repository_path, query.branch.clone()).await?;

let dl_branch = if let Some(branch) = query.branch.clone() {
Expand All @@ -56,7 +59,7 @@ pub async fn handle(
Arc::new(open_repo.latest_commit().await?)
};

Ok(into_response(&View {
Ok(into_response(View {
repo,
commit,
branch: query.branch,
Expand Down
9 changes: 6 additions & 3 deletions src/methods/repo/diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ use axum::{
use crate::{
git::Commit,
http, into_response,
methods::repo::{commit::UriQuery, Repository, RepositoryPath, Result},
methods::{
filters,
repo::{commit::UriQuery, Repository, RepositoryPath, Result},
},
Git,
};

Expand All @@ -28,15 +31,15 @@ pub async fn handle(
Extension(RepositoryPath(repository_path)): Extension<RepositoryPath>,
Extension(git): Extension<Arc<Git>>,
Query(query): Query<UriQuery>,
) -> Result<Response> {
) -> Result<impl IntoResponse> {
let open_repo = git.repo(repository_path, query.branch.clone()).await?;
let commit = if let Some(commit) = query.id {
open_repo.commit(&commit).await?
} else {
Arc::new(open_repo.latest_commit().await?)
};

Ok(into_response(&View {
Ok(into_response(View {
repo,
commit,
branch: query.branch,
Expand Down
13 changes: 5 additions & 8 deletions src/methods/repo/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ use std::sync::Arc;

use anyhow::Context;
use askama::Template;
use axum::{extract::Query, response::Response, Extension};
use axum::{extract::Query, response::IntoResponse, Extension};
use serde::Deserialize;
use yoke::Yoke;

use crate::{
database::schema::{commit::YokedCommit, repository::YokedRepository},
Expand All @@ -25,9 +24,9 @@ pub struct UriQuery {

#[derive(Template)]
#[template(path = "repo/log.html")]
pub struct View<'a> {
pub struct View {
repo: Repository,
commits: Vec<&'a crate::database::schema::commit::Commit<'a>>,
commits: Vec<YokedCommit>,
next_offset: Option<u64>,
branch: Option<String>,
}
Expand All @@ -36,7 +35,7 @@ pub async fn handle(
Extension(repo): Extension<Repository>,
Extension(db): Extension<Arc<rocksdb::DB>>,
Query(query): Query<UriQuery>,
) -> Result<Response> {
) -> Result<impl IntoResponse> {
tokio::task::spawn_blocking(move || {
let offset = query.offset.unwrap_or(0);

Expand All @@ -52,9 +51,7 @@ pub async fn handle(
None
};

let commits = commits.iter().map(Yoke::get).collect();

Ok(into_response(&View {
Ok(into_response(View {
repo,
commits,
next_offset,
Expand Down
6 changes: 3 additions & 3 deletions src/methods/repo/refs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::{collections::BTreeMap, sync::Arc};

use anyhow::Context;
use askama::Template;
use axum::{response::Response, Extension};
use axum::{response::IntoResponse, Extension};

use crate::{
into_response,
Expand All @@ -23,7 +23,7 @@ pub struct View {
pub async fn handle(
Extension(repo): Extension<Repository>,
Extension(db): Extension<Arc<rocksdb::DB>>,
) -> Result<Response> {
) -> Result<impl IntoResponse> {
tokio::task::spawn_blocking(move || {
let repository = crate::database::schema::repository::Repository::open(&db, &*repo)?
.context("Repository does not exist")?;
Expand All @@ -40,7 +40,7 @@ pub async fn handle(

let tags = repository.get().tag_tree(db).fetch_all()?;

Ok(into_response(&View {
Ok(into_response(View {
repo,
refs: Refs { heads, tags },
branch: None,
Expand Down
14 changes: 6 additions & 8 deletions src/methods/repo/summary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ use std::{collections::BTreeMap, sync::Arc};

use anyhow::Context;
use askama::Template;
use axum::{response::Response, Extension};
use yoke::Yoke;
use axum::{response::IntoResponse, Extension};

use crate::{
database::schema::{commit::YokedCommit, repository::YokedRepository},
Expand All @@ -16,22 +15,21 @@ use crate::{

#[derive(Template)]
#[template(path = "repo/summary.html")]
pub struct View<'a> {
pub struct View {
repo: Repository,
refs: Refs,
commit_list: Vec<&'a crate::database::schema::commit::Commit<'a>>,
commit_list: Vec<YokedCommit>,
branch: Option<Arc<str>>,
}

pub async fn handle(
Extension(repo): Extension<Repository>,
Extension(db): Extension<Arc<rocksdb::DB>>,
) -> Result<Response> {
) -> Result<impl IntoResponse> {
tokio::task::spawn_blocking(move || {
let repository = crate::database::schema::repository::Repository::open(&db, &*repo)?
.context("Repository does not exist")?;
let commits = get_default_branch_commits(&repository, &db)?;
let commit_list = commits.iter().map(Yoke::get).collect();

let mut heads = BTreeMap::new();
for head in repository.get().heads(&db)?.get() {
Expand All @@ -45,10 +43,10 @@ pub async fn handle(

let tags = repository.get().tag_tree(db).fetch_all()?;

Ok(into_response(&View {
Ok(into_response(View {
repo,
refs: Refs { heads, tags },
commit_list,
commit_list: commits,
branch: None,
}))
})
Expand Down
Loading

0 comments on commit a254a4a

Please sign in to comment.