Skip to content
This repository has been archived by the owner on Mar 9, 2023. It is now read-only.

Commit

Permalink
Gloo Workers v2 (#214)
Browse files Browse the repository at this point in the history
* Add First Webworker

* Web Workers

An attempt was made

* Add Reproduction Test

* Use Gloo Workers v2

* Check Upstream

* Get It Working

* Rework
  • Loading branch information
droogmic authored Jun 19, 2022
1 parent 762b74d commit ab1c1da
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 34 deletions.
6 changes: 3 additions & 3 deletions osm2lanes-web/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
name = "osm2lanes-web"
version = "0.1.0"
description = "Website for osm2lanes"
readme = true
repository = "https://github.com/a-b-street/osm2lanes"
license = "Apache-2.0"
keywords = ["osm", "lanes", "web"]
Expand All @@ -15,9 +14,9 @@ edition = "2021"

[dependencies]
console_log = { version = "0.2", optional = true, features = ["color"] }
console_error_panic_hook = "0.1"
geo = { version = "0.20" }
gloo-utils = "0.1"
gloo-timers = "0.2"
leaflet = { git = "https://github.com/droogmic/leaflet-rs", branch = "polyline_get_bounds" }
log = "0.4"
osm-tags = { path = "../osm-tags" }
Expand All @@ -28,10 +27,11 @@ serde = { version = "1", features = ["derive"] }
serde_json = "1"
syntect = { version = "5.0", default-features = false, features = [
"default-fancy",
] } # TODO: https://github.com/trishume/syntect/issues/135#issuecomment-700306068, webwroker + create json bundle
] } # TODO: https://github.com/trishume/syntect/issues/135#issuecomment-700306068, webworker + create json bundle
wasm-bindgen = "0.2"
wee_alloc = { version = "0.4", optional = true }
yew = "0.19"
gloo-worker = { git = "https://github.com/futursolo/gloo", rev = "a2101e166260294292c8121fdb8ed883dae62ed8" }

[dependencies.web-sys]
version = "0.3"
Expand Down
6 changes: 5 additions & 1 deletion osm2lanes-web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@
integrity="sha512-BB3hKbKWOc9Ez/TAwyWxNXeoV9c1v6FIeYiBieIWkpLjauysF18NzgR1MBNBXf8/KABdlkX68nAhlwcDFLGPCQ=="
crossorigin></script>
<link rel="stylesheet" href="//unpkg.com/leaflet-gesture-handling/dist/leaflet-gesture-handling.min.css"
type="text/css" />
type="text/css">
<script src="https://unpkg.com/leaflet-gesture-handling"></script>

<!-- Web Workers -->
<link data-trunk rel="rust" href="Cargo.toml" data-bin="app" data-type="main" />
<link data-trunk rel="rust" href="Cargo.toml" data-bin="worker" data-type="worker" />
</head>

</html>
56 changes: 56 additions & 0 deletions osm2lanes-web/src/agent.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use gloo_worker::{Codec, HandlerId, Worker, WorkerScope};
use osm2lanes::test::{get_tests, TestCase};
use serde::{Deserialize, Serialize};
use wasm_bindgen::JsValue;

pub struct JsonCodec;

impl Codec for JsonCodec {
fn encode<I>(input: I) -> JsValue
where
I: Serialize,
{
let data = serde_json::to_string(&input).expect("can't serialize worker message");
log::trace!("message in: {data}");
JsValue::from_str(&data)
}

fn decode<O>(input: JsValue) -> O
where
O: for<'de> Deserialize<'de>,
{
let data = input.as_string().expect("JsValue string");
log::trace!("message out: {data}");
serde_json::from_str(&data).expect("can't deserialize worker message")
}
}

pub(crate) const NAME: &str = "worker.js";

pub struct ExampleLoader;

#[derive(Serialize, Deserialize)]
pub struct ExampleLoaderOutput(pub Vec<TestCase>);

impl Worker for ExampleLoader {
type Message = ();
type Input = ();
type Output = ExampleLoaderOutput;

fn create(_scope: &WorkerScope<Self>) -> Self {
Self
}

fn update(&mut self, _scope: &WorkerScope<Self>, _msg: Self::Message) {
// no messaging
}

fn received(&mut self, scope: &WorkerScope<Self>, _msg: Self::Input, id: HandlerId) {
let tests = get_tests();
let examples = tests
.into_iter()
.filter(|t| t.example().is_some())
.collect();
scope.respond(id, ExampleLoaderOutput(examples));
}
}
8 changes: 8 additions & 0 deletions osm2lanes-web/src/bin/app.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use osm2lanes_web::App;

fn main() {
console_error_panic_hook::set_once();
console_log::init_with_level(log::Level::Debug).expect("logging failed");
log::trace!("Initializing yew...");
yew::start_app::<App>();
}
11 changes: 11 additions & 0 deletions osm2lanes-web/src/bin/worker.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use gloo_worker::Registrable;
use osm2lanes_web::agent::{ExampleLoader, JsonCodec};

fn main() {
console_error_panic_hook::set_once();
console_log::init_with_level(log::Level::Debug).expect("logging failed");
log::trace!("Initializing worker...");
ExampleLoader::registrar()
.encoding::<JsonCodec>()
.register();
}
48 changes: 29 additions & 19 deletions osm2lanes-web/src/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@ use std::cell::RefCell;
use std::collections::BTreeMap;
use std::rc::Rc;

use gloo_timers::callback::Timeout;
use gloo_worker::{WorkerBridge, WorkerSpawner};
use osm2lanes::locale::{Country, DrivingSide, Locale};
use osm2lanes::test::{get_tests, TestCase};
use osm2lanes::test::TestCase;
use web_sys::{Event, FocusEvent, HtmlInputElement, HtmlSelectElement, KeyboardEvent, MouseEvent};
use yew::{html, Callback, Component, Context, Html, NodeRef, Properties, TargetCast};

use crate::agent::{ExampleLoader, ExampleLoaderOutput, JsonCodec, NAME};
use crate::{Msg as AppMsg, State};

pub(crate) enum Msg {
/// Pass the message to the parent
Up(Box<AppMsg>),
FirstLazy,
/// Worker's response with examples
WorkerMsg(ExampleLoaderOutput),
/// Select example given name
Example(String),
}

Expand All @@ -28,8 +32,8 @@ pub(crate) struct Props {
pub(crate) state: Rc<RefCell<State>>,
}

#[derive(Default)]
pub(crate) struct Control {
_worker: WorkerBridge<ExampleLoader>,
textarea_input_ref: NodeRef,
textarea_output_ref: NodeRef,
example: Option<String>,
Expand All @@ -40,16 +44,32 @@ impl Component for Control {
type Properties = Props;
type Message = Msg;

fn create(_ctx: &Context<Self>) -> Self {
Self::default()
fn create(ctx: &Context<Self>) -> Self {
let link = ctx.link().clone();
let cb = move |output| link.send_message(Self::Message::WorkerMsg(output));
let worker = WorkerSpawner::<ExampleLoader>::new()
.encoding::<JsonCodec>()
.callback(cb)
.spawn(NAME);

// Trigger worker
worker.send(());

Self {
_worker: worker,
textarea_input_ref: NodeRef::default(),
textarea_output_ref: NodeRef::default(),
example: Option::default(),
examples: Option::default(),
}
}

fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool {
match msg {
Msg::Up(msg) => ctx.props().callback_msg.emit(*msg),
Msg::FirstLazy => {
let tests = get_tests();
let examples: BTreeMap<_, _> = tests
Msg::WorkerMsg(examples) => {
let examples: BTreeMap<String, TestCase> = examples
.0
.into_iter()
.filter_map(|t| {
let example_name = t.example().map(std::borrow::ToOwned::to_owned);
Expand Down Expand Up @@ -256,14 +276,4 @@ impl Component for Control {
</>
}
}

fn rendered(&mut self, ctx: &Context<Self>, first_render: bool) {
if first_render {
let handle = {
let link = ctx.link().clone();
Timeout::new(1, move || link.send_message(Msg::FirstLazy))
};
handle.forget();
}
}
}
10 changes: 3 additions & 7 deletions osm2lanes-web/src/main.rs → osm2lanes-web/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#![warn(unreachable_pub)]
#![deny(unsafe_code)]
#![deny(unsafe_op_in_unsafe_fn)]
#![warn(unused_crate_dependencies)]
// #![warn(unused_crate_dependencies)] // https://github.com/rust-lang/rust/issues/57274
#![warn(unused_lifetimes)]
#![warn(unused_qualifications)]
// Clippy
Expand Down Expand Up @@ -57,6 +57,8 @@ use syntect::parsing::SyntaxSet;
use web_sys::HtmlInputElement;
use yew::prelude::*;

pub mod agent;

mod control;
use control::Control;

Expand Down Expand Up @@ -361,9 +363,3 @@ impl App {
}
}
}

fn main() {
console_log::init_with_level(log::Level::Debug).expect("logging failed");
log::trace!("Initializing yew...");
yew::start_app::<App>();
}
2 changes: 1 addition & 1 deletion osm2lanes/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#![warn(unreachable_pub)]
#![deny(unsafe_code)]
#![deny(unsafe_op_in_unsafe_fn)]
// #![warn(unused_crate_dependencies)] // TODO: report upstream
// #![warn(unused_crate_dependencies)] // https://github.com/rust-lang/rust/issues/57274
#![warn(unused_lifetimes)]
#![warn(unused_qualifications)]
// Clippy
Expand Down
31 changes: 28 additions & 3 deletions osm2lanes/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::locale::DrivingSide;
use crate::road::{Lane, Road};

#[derive(Clone)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(untagged, deny_unknown_fields))]
pub enum RustTesting {
Enabled(bool),
Expand All @@ -16,7 +16,7 @@ pub enum RustTesting {
}

#[derive(Clone)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
pub enum Expected {
Road(Road),
Expand All @@ -26,7 +26,7 @@ pub enum Expected {

#[allow(clippy::module_name_repetitions)]
#[derive(Clone)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct TestCase {
// Metadata
/// The OSM way unique identifier
Expand Down Expand Up @@ -478,6 +478,31 @@ mod tests {
});
}

#[test]
fn test_json() {
env_logger_init();
let tests = get_tests();
for test in &tests {
serde_json::to_string(&test.tags).expect("can't serialize tags");
match &test.expected {
Expected::Road(expected_road) => {
serde_json::to_string(&expected_road.lanes)
.expect("can't serialize expected road lanes");
serde_json::to_string(&expected_road.highway)
.expect("can't serialize expected road highway");
serde_json::to_string(&expected_road).expect("can't serialize expected road");
},
Expected::Output(expected_output) => {
serde_json::to_string(expected_output)
.expect("can't serialize expected output");
},
}
serde_json::to_string(&test.expected).expect("can't serialize expected");
serde_json::to_string(&test).expect("can't serialize test case");
}
serde_json::to_string(&tests).expect("can't serialize test cases");
}

#[test]
fn test_from_data() {
env_logger_init();
Expand Down

0 comments on commit ab1c1da

Please sign in to comment.