make blag worse
This commit is contained in:
parent
aec4756c6f
commit
8a05a21bb5
2 changed files with 62 additions and 43 deletions
|
@ -3,6 +3,7 @@ use std::sync::Arc;
|
||||||
use askama_axum::Template;
|
use askama_axum::Template;
|
||||||
use axum::http::StatusCode;
|
use axum::http::StatusCode;
|
||||||
use axum::response::{IntoResponse, Response};
|
use axum::response::{IntoResponse, Response};
|
||||||
|
use color_eyre::eyre;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
|
@ -17,6 +18,8 @@ pub enum PostError {
|
||||||
RenderError(String),
|
RenderError(String),
|
||||||
#[error("post {0:?} not found")]
|
#[error("post {0:?} not found")]
|
||||||
NotFound(Arc<str>),
|
NotFound(Arc<str>),
|
||||||
|
#[error("unexpected: {0}")]
|
||||||
|
Other(#[from] eyre::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<fronma::error::Error> for PostError {
|
impl From<fronma::error::Error> for PostError {
|
||||||
|
|
102
src/post/blag.rs
102
src/post/blag.rs
|
@ -38,10 +38,11 @@ struct BlagMetadata {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub tags: BTreeSet<Arc<str>>,
|
pub tags: BTreeSet<Arc<str>>,
|
||||||
pub dont_cache: bool,
|
pub dont_cache: bool,
|
||||||
|
pub raw: Option<Arc<str>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlagMetadata {
|
impl BlagMetadata {
|
||||||
pub fn into_full(self, name: Arc<str>) -> (PostMetadata, bool) {
|
pub fn into_full(self, name: Arc<str>) -> (PostMetadata, bool, Option<Arc<str>>) {
|
||||||
(
|
(
|
||||||
PostMetadata {
|
PostMetadata {
|
||||||
name,
|
name,
|
||||||
|
@ -56,6 +57,7 @@ impl BlagMetadata {
|
||||||
tags: self.tags.into_iter().collect(),
|
tags: self.tags.into_iter().collect(),
|
||||||
},
|
},
|
||||||
self.dont_cache,
|
self.dont_cache,
|
||||||
|
self.raw,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,6 +69,11 @@ pub struct Blag {
|
||||||
_fastblag: bool,
|
_fastblag: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum RenderResult {
|
||||||
|
Normal(PostMetadata, String, (Duration, Duration), bool),
|
||||||
|
Raw(Vec<u8>, Arc<str>),
|
||||||
|
}
|
||||||
|
|
||||||
impl Blag {
|
impl Blag {
|
||||||
pub fn new(root: Arc<Path>, blag_bin: Arc<Path>, cache: Option<Arc<CacheGuard>>) -> Blag {
|
pub fn new(root: Arc<Path>, blag_bin: Arc<Path>, cache: Option<Arc<CacheGuard>>) -> Blag {
|
||||||
Self {
|
Self {
|
||||||
|
@ -82,7 +89,7 @@ impl Blag {
|
||||||
name: Arc<str>,
|
name: Arc<str>,
|
||||||
path: impl AsRef<Path>,
|
path: impl AsRef<Path>,
|
||||||
query_json: String,
|
query_json: String,
|
||||||
) -> Result<(PostMetadata, String, (Duration, Duration), bool), PostError> {
|
) -> Result<RenderResult, PostError> {
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
|
||||||
debug!(%name, "rendering");
|
debug!(%name, "rendering");
|
||||||
|
@ -91,6 +98,8 @@ impl Blag {
|
||||||
.arg(path.as_ref())
|
.arg(path.as_ref())
|
||||||
.env("BLAG_QUERY", query_json)
|
.env("BLAG_QUERY", query_json)
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
|
.stderr(Stdio::inherit())
|
||||||
|
.stdin(Stdio::null())
|
||||||
.spawn()
|
.spawn()
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
error!("failed to spawn {:?}: {err}", self.blag_bin);
|
error!("failed to spawn {:?}: {err}", self.blag_bin);
|
||||||
|
@ -105,24 +114,36 @@ impl Blag {
|
||||||
|
|
||||||
let blag_meta: BlagMetadata = serde_json::from_str(&buf)?;
|
let blag_meta: BlagMetadata = serde_json::from_str(&buf)?;
|
||||||
debug!("blag meta: {blag_meta:?}");
|
debug!("blag meta: {blag_meta:?}");
|
||||||
let (meta, dont_cache) = blag_meta.into_full(name);
|
let (meta, dont_cache, raw) = blag_meta.into_full(name);
|
||||||
|
|
||||||
|
// this is morally reprehensible
|
||||||
|
if let Some(raw) = raw {
|
||||||
|
let mut buf = buf.into_bytes();
|
||||||
|
reader.read_to_end(&mut buf).await?;
|
||||||
|
return Ok(RenderResult::Raw(buf, raw));
|
||||||
|
}
|
||||||
|
|
||||||
let parsed = start.elapsed();
|
let parsed = start.elapsed();
|
||||||
|
|
||||||
let rendering = Instant::now();
|
let rendering = Instant::now();
|
||||||
|
|
||||||
buf.clear();
|
buf.clear();
|
||||||
reader.read_to_string(&mut buf).await?;
|
reader.read_to_string(&mut buf).await?;
|
||||||
|
|
||||||
debug!("read output: {} bytes", buf.len());
|
let status = cmd.wait().await?;
|
||||||
|
debug!("exited: {status}");
|
||||||
let exit_status = cmd.wait().await?;
|
if !status.success() {
|
||||||
debug!("exited: {exit_status}");
|
return Err(PostError::RenderError(status.to_string()));
|
||||||
if !exit_status.success() {
|
|
||||||
return Err(PostError::RenderError(exit_status.to_string()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let rendered = rendering.elapsed();
|
let rendered = rendering.elapsed();
|
||||||
|
|
||||||
Ok((meta, buf, (parsed, rendered), dont_cache))
|
Ok(RenderResult::Normal(
|
||||||
|
meta,
|
||||||
|
buf,
|
||||||
|
(parsed, rendered),
|
||||||
|
dont_cache,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,46 +254,41 @@ impl PostManager for Blag {
|
||||||
query_json.hash(&mut hasher);
|
query_json.hash(&mut hasher);
|
||||||
let query_hash = hasher.finish();
|
let query_hash = hasher.finish();
|
||||||
|
|
||||||
let post = if let Some(cache) = &self.cache {
|
let post = if let Some(cache) = &self.cache
|
||||||
if let Some(CacheValue { meta, body, .. }) =
|
&& let Some(CacheValue { meta, body, .. }) =
|
||||||
cache.lookup(name.clone(), mtime, query_hash).await
|
cache.lookup(name.clone(), mtime, query_hash).await
|
||||||
{
|
{
|
||||||
ReturnedPost::Rendered {
|
ReturnedPost::Rendered {
|
||||||
meta,
|
meta,
|
||||||
body,
|
body,
|
||||||
perf: RenderStats::Cached(start.elapsed()),
|
perf: RenderStats::Cached(start.elapsed()),
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let (meta, content, (parsed, rendered), dont_cache) =
|
|
||||||
self.render(name.clone(), path, query_json).await?;
|
|
||||||
let body = content.into();
|
|
||||||
|
|
||||||
if !dont_cache {
|
|
||||||
cache
|
|
||||||
.insert(name, meta.clone(), mtime, Arc::clone(&body), query_hash)
|
|
||||||
.await
|
|
||||||
.unwrap_or_else(|err| warn!("failed to insert {:?} into cache", err.0));
|
|
||||||
}
|
|
||||||
|
|
||||||
let total = start.elapsed();
|
|
||||||
ReturnedPost::Rendered {
|
|
||||||
meta,
|
|
||||||
body,
|
|
||||||
perf: RenderStats::Rendered {
|
|
||||||
total,
|
|
||||||
parsed,
|
|
||||||
rendered,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let (meta, content, (parsed, rendered), ..) =
|
let (meta, content, (parsed, rendered), dont_cache) =
|
||||||
self.render(name, path, query_json).await?;
|
match self.render(name.clone(), path, query_json).await? {
|
||||||
|
RenderResult::Normal(x, y, z, w) => (x, y, z, w),
|
||||||
|
RenderResult::Raw(buffer, content_type) => {
|
||||||
|
return Ok(ReturnedPost::Raw {
|
||||||
|
buffer,
|
||||||
|
content_type: HeaderValue::from_str(&content_type)
|
||||||
|
.map_err(Into::into)
|
||||||
|
.map_err(PostError::Other)?,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let body = content.into();
|
||||||
|
|
||||||
|
if !dont_cache && let Some(cache) = &self.cache {
|
||||||
|
cache
|
||||||
|
.insert(name, meta.clone(), mtime, Arc::clone(&body), query_hash)
|
||||||
|
.await
|
||||||
|
.unwrap_or_else(|err| warn!("failed to insert {:?} into cache", err.0));
|
||||||
|
}
|
||||||
|
|
||||||
let total = start.elapsed();
|
let total = start.elapsed();
|
||||||
ReturnedPost::Rendered {
|
ReturnedPost::Rendered {
|
||||||
meta,
|
meta,
|
||||||
body: content.into(),
|
body,
|
||||||
perf: RenderStats::Rendered {
|
perf: RenderStats::Rendered {
|
||||||
total,
|
total,
|
||||||
parsed,
|
parsed,
|
||||||
|
|
Loading…
Reference in a new issue