Skip to content

Commit 0ce54c4

Browse files
committed
Move running the solutions to use web workers, not blocking the main rendering
1 parent 5501ad2 commit 0ce54c4

File tree

13 files changed

+337
-86
lines changed

13 files changed

+337
-86
lines changed

Cargo.lock

Lines changed: 192 additions & 28 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

aoc-web/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ edition = "2021"
88
itertools = "0.12.0"
99
log = "0.4.20"
1010
yew = { version = "0.21.0", features = ["csr"] }
11+
yew-agent = "0.3.0"
1112
yew-router = "0.18"
1213
wasm-logger = "0.2.0"
1314
wasm-bindgen = "0.2.88"
@@ -17,3 +18,8 @@ gloo = "0.10.0"
1718
syntect = { version = "5.1.0", default-features = false, features = [
1819
"default-fancy",
1920
] }
21+
serde = { version = "1.0.194", features = ["derive"] }
22+
chrono = { version = "0.4.31", default-features = false, features = [
23+
"clock",
24+
"wasmbind",
25+
] }

aoc-web/index.html

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,25 @@
1717

1818
<base data-trunk-public-url />
1919

20-
<link data-trunk rel="rust" data-bin="aoc-web" />
20+
<link
21+
data-trunk
22+
rel="rust"
23+
href="Cargo.toml"
24+
data-bin="app"
25+
data-type="main"
26+
data-wasm-opt="4"
27+
data-weak-refs
28+
/>
29+
<link
30+
data-trunk
31+
rel="rust"
32+
href="Cargo.toml"
33+
data-bin="worker"
34+
data-type="worker"
35+
data-wasm-opt="4"
36+
data-weak-refs
37+
/>
38+
2139
<link data-trunk rel="css" href="static/styles.css" />
2240
<link data-trunk rel="copy-file" href="static/_redirects" />
2341
<link data-trunk rel="copy-file" href="static/fragment.glsl" />

aoc-web/src/agent.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
use chrono::Local;
2+
use yew_agent::prelude::*;
3+
4+
use aoc_solver::{solution::Solver, y2020::Y2020, y2021::Y2021, y2022::Y2022, y2023::Y2023};
5+
6+
#[oneshot]
7+
pub async fn SolutionTask(input: (u32, u8)) -> (String, i64) {
8+
let (year, day) = input;
9+
10+
let start = Local::now();
11+
12+
let output = match year {
13+
2020 => Y2020::run_solution(day, None),
14+
2021 => Y2021::run_solution(day, None),
15+
2022 => Y2022::run_solution(day, None),
16+
2023 => Y2023::run_solution(day, None),
17+
_ => vec!["Missing year".to_string()],
18+
};
19+
20+
let duration = (Local::now() - start).num_milliseconds();
21+
22+
(output.join("\n"), duration)
23+
}

aoc-web/src/bin/app.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
use yew::prelude::*;
2+
3+
use aoc_web::{footer::Footer, router::Router};
4+
5+
#[function_component(App)]
6+
fn app() -> Html {
7+
html! {
8+
<>
9+
<Router/>
10+
<Footer />
11+
</>
12+
}
13+
}
14+
15+
fn main() {
16+
let document = gloo::utils::document();
17+
let container = document.query_selector("#aoc").unwrap().unwrap();
18+
19+
yew::Renderer::<App>::with_root(container).render();
20+
wasm_logger::init(wasm_logger::Config::default());
21+
}

aoc-web/src/bin/worker.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
use yew_agent::Registrable;
2+
3+
use aoc_web::agent::SolutionTask;
4+
5+
fn main() {
6+
SolutionTask::registrar().register();
7+
}

aoc-web/src/footer.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use yew::prelude::*;
2+
3+
#[function_component(Footer)]
4+
pub fn footer() -> Html {
5+
html! {
6+
<footer>
7+
<small>
8+
{"Made by "}
9+
<a href="https://github.com/Cadiac">{"Cadiac"}</a>
10+
{". Source code can be be found "}
11+
<a href="https://github.com/Cadiac/adventofcode">{"here"}</a>
12+
{"."}
13+
</small>
14+
</footer>
15+
}
16+
}

aoc-web/src/header.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use yew::prelude::*;
22

3-
use crate::{year::Year, NavLink, Route};
3+
use crate::{navlink::NavLink, router::Route, year::Year};
44

55
#[derive(Properties, PartialEq)]
66
pub struct HeaderProps {

aoc-web/src/lib.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
pub mod agent;
2+
pub mod footer;
3+
pub mod header;
4+
pub mod home;
5+
pub mod navlink;
6+
pub mod router;
7+
pub mod solution;
8+
pub mod year;
9+
10+
pub mod y2020;
11+
pub mod y2021;
12+
pub mod y2022;
13+
pub mod y2023;

aoc-web/src/navlink.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use yew::prelude::*;
22
use yew_router::components::Link;
33

4-
use crate::Route;
4+
use crate::router::Route;
55

66
#[derive(Properties, PartialEq)]
77
pub struct NavLinkProps {
Lines changed: 13 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,8 @@
1-
pub mod header;
2-
pub mod home;
3-
pub mod navlink;
4-
pub mod solution;
5-
pub mod y2020;
6-
pub mod y2021;
7-
pub mod y2022;
8-
pub mod y2023;
9-
pub mod year;
10-
11-
use home::Home;
121
use yew::prelude::*;
2+
use yew_agent::oneshot::OneshotProvider;
133
use yew_router::prelude::*;
144

15-
use crate::{header::Header, navlink::NavLink, solution::Solution};
5+
use crate::{agent::SolutionTask, header::Header, home::Home, solution::Solution, y2022};
166

177
#[derive(Clone, Routable, PartialEq)]
188
pub enum Route {
@@ -33,7 +23,7 @@ pub enum Route {
3323
NotFound,
3424
}
3525

36-
fn router(route: Route) -> Html {
26+
pub fn switch(route: Route) -> Html {
3727
let year = match route {
3828
Route::Index | Route::NotFound => 2023,
3929
Route::Solution { year, day: _ } | Route::Home { year } => year,
@@ -61,42 +51,20 @@ fn router(route: Route) -> Html {
6151
html! {
6252
<>
6353
<Header year={year} route={route} />
64-
<main class="fade-in">{ main }</main>
54+
<main class="fade-in">
55+
<OneshotProvider<SolutionTask> path="/worker.js">
56+
{ main }
57+
</OneshotProvider<SolutionTask>>
58+
</main>
6559
</>
6660
}
6761
}
6862

69-
#[function_component(Footer)]
70-
fn footer() -> Html {
71-
html! {
72-
<footer>
73-
<small>
74-
{"Made by "}
75-
<a href="https://github.com/Cadiac">{"Cadiac"}</a>
76-
{". Source code can be be found "}
77-
<a href="https://github.com/Cadiac/adventofcode">{"here"}</a>
78-
{"."}
79-
</small>
80-
</footer>
81-
}
82-
}
83-
84-
#[function_component(App)]
85-
fn app() -> Html {
63+
#[function_component(Router)]
64+
pub fn router() -> Html {
8665
html! {
87-
<>
88-
<BrowserRouter>
89-
<Switch<Route> render={router} />
90-
</BrowserRouter>
91-
<Footer />
92-
</>
66+
<BrowserRouter>
67+
<Switch<Route> render={switch} />
68+
</BrowserRouter>
9369
}
9470
}
95-
96-
fn main() {
97-
let document = gloo::utils::document();
98-
let container = document.query_selector("#aoc").unwrap().unwrap();
99-
100-
yew::Renderer::<App>::with_root(container).render();
101-
wasm_logger::init(wasm_logger::Config::default());
102-
}

aoc-web/src/solution.rs

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
use yew::platform::spawn_local;
12
use yew::prelude::*;
3+
use yew_agent::oneshot::use_oneshot_runner;
24

35
use syntect::highlighting::ThemeSet;
46
use syntect::html::highlighted_html_for_string;
57
use syntect::parsing::{SyntaxDefinition, SyntaxSetBuilder};
68

9+
use crate::agent::SolutionTask;
710
use aoc_solver::solution::Solver;
811
use aoc_solver::y2020::Y2020;
912
use aoc_solver::y2021::Y2021;
@@ -16,8 +19,6 @@ pub struct Props {
1619
pub year: u32,
1720
}
1821

19-
use yew::{function_component, Html, Properties};
20-
2122
#[function_component(SourceViewer)]
2223
pub fn source_viewer(props: &Props) -> Html {
2324
let highlighted = use_memo((props.year, props.day), |(year, day)| {
@@ -51,18 +52,32 @@ pub fn source_viewer(props: &Props) -> Html {
5152

5253
#[function_component(Solution)]
5354
pub fn solution(props: &Props) -> Html {
54-
let output = match props.year {
55-
2020 => Y2020::run_solution(props.day, None),
56-
2021 => Y2021::run_solution(props.day, None),
57-
2022 => Y2022::run_solution(props.day, None),
58-
2023 => Y2023::run_solution(props.day, None),
59-
_ => vec!["Unknown year".to_string()],
55+
let output = use_state(|| "".to_string());
56+
let solution_task = use_oneshot_runner::<SolutionTask>();
57+
58+
let run_solution = {
59+
let output = output.clone();
60+
61+
move |input: (u32, u8)| {
62+
let solution_agent = solution_task.clone();
63+
let output = output.clone();
64+
output.set("Running...".to_string());
65+
66+
spawn_local(async move {
67+
let (output_value, duration) = solution_agent.run(input).await;
68+
output.set(format!("{output_value}\n{duration} ms"));
69+
});
70+
}
6071
};
6172

73+
let input = (props.year, props.day);
74+
75+
use_effect_with((props.day, props.year), move |_| run_solution(input));
76+
6277
html! {
6378
<div class="fade-in">
6479
<pre>
65-
<code>{ output.join("\n") }</code>
80+
<code>{ &*output }</code>
6681
</pre>
6782
<SourceViewer year={props.year} day={props.day} />
6883
</div>

aoc-web/src/year.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use yew::prelude::*;
22
use yew_router::components::Link;
33

4-
use crate::Route;
4+
use crate::router::Route;
55

66
const YEARS: &[u32] = &[2023, 2022, 2021, 2020];
77

0 commit comments

Comments
 (0)