index : paprika

A blogging platform written in Rust for Cloudflare Workers, integrated with Standard Notes

diff options
context:
space:
mode:
authorPeter Cai <[email protected]>2020-04-18 16:46:11 +0800
committerPeter Cai <[email protected]>2020-04-18 16:46:11 +0800
commit5c2615a6cbea62d69717dde2deb7bed3e494a06f (patch)
treea884b757fd741fa5da0899e50f0105cb0f8c802c
parente0d8c949866a9487e08452ba7e3dde14282cfa96 (diff)
downloadpaprika-5c2615a6cbea62d69717dde2deb7bed3e494a06f.tar.gz
blog: get rid of Vec allocation in render for good
just spawn the cache whitelist task onto the js ev loop and don't care about it; the write only need to succeed once and that normally happens at the very first time.
-rw-r--r--src/blog.rs43
1 files changed, 22 insertions, 21 deletions
diff --git a/src/blog.rs b/src/blog.rs
index 3a5bbd1..86d013d 100644
--- a/src/blog.rs
+++ b/src/blog.rs
@@ -9,10 +9,10 @@ use crate::utils::*;
use js_sys::{JsString, RegExp};
use pulldown_cmark::*;
use serde::{Serialize, Deserialize};
-use std::future::Future;
use std::vec::Vec;
use wasm_bindgen::JsCast;
use wasm_bindgen::closure::Closure;
+use wasm_bindgen_futures::spawn_local;
// A list of the UUIDs of all published blog posts
// This should be SORTED with the newest posts at lower indices (closer to 0)
@@ -215,16 +215,25 @@ impl PostContentCache {
Some(cache)
}
- async fn transform_tag<'a>(tag: &mut Tag<'a>) {
+ fn transform_tag<'a>(tag: &mut Tag<'a>) {
match tag {
Tag::Image(_, url, _) => {
// Convert all external image to our cached URL
// to protect users and speed up page loading
let url_encoded: String = js_sys::encode_uri_component(url).into();
// Also write this URL to whitelist
+ // (just throw the task onto the JS ev loop,
+ // because to make this function async we MUST need to
+ // allocate Vec later in the render function)
// we don't care about if this write succeeds or not,
// because even if it breaks we still can recover by a simple refresh
- let _ = store::put_str(&Self::url_to_cache_whitelist_key(url), "Y").await;
+ // and once it's written, it's permanent, so we expect the write
+ // to succeed as soon as the article is submitted
+ let url_cache_key = Self::url_to_cache_whitelist_key(url);
+ spawn_local(async move {
+ let _ = store::put_str(&url_cache_key, "Y").await;
+ ()
+ });
// Now we can overwrite the tag URL
*url = format!("{}{}", IMG_CACHE_PREFIX, url_encoded).into();
},
@@ -233,17 +242,15 @@ impl PostContentCache {
}
fn transform_tags<'ev>(
- parser: impl 'ev + Iterator<Item = Event<'ev>>
- ) -> impl 'ev + Iterator<Item = impl Future<Output = Event<'ev>>> {
+ parser: impl Iterator<Item = Event<'ev>>
+ ) -> impl Iterator<Item = Event<'ev>> {
parser.map(|mut ev| {
- async {
- match ev {
- Event::Start(ref mut tag) | Event::End(ref mut tag) => {
- Self::transform_tag(tag).await;
- ev
- },
- _ => ev
- }
+ match ev {
+ Event::Start(ref mut tag) | Event::End(ref mut tag) => {
+ Self::transform_tag(tag);
+ ev
+ },
+ _ => ev
}
})
}
@@ -329,17 +336,11 @@ impl PostContentCache {
let parser = Parser::new_ext(&post.content, Options::all());
// Apply code highlighting via Highlight.js
let parser = Self::transform_code_block_highlight(parser);
- // Apply async tag transform (resulting in an iterator of Futures)
+ // Apply tag transform
let parser = Self::transform_tags(parser);
- // Await on every Future in the queue to convert them back as Events
- let mut events: Vec<Event> = vec![];
- for ev in parser {
- events.push(ev.await);
- }
-
let mut html_output = String::new();
- html::push_html(&mut html_output, events.into_iter());
+ html::push_html(&mut html_output, parser);
html_output = Self::transform_html(html_output);
PostContentCache {
uuid: post.uuid.clone(),