-
Notifications
You must be signed in to change notification settings - Fork 146
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Fix typo. * Move worker into actor folder. * Add some oneshot implementation. * Finish oneshot worker. * Strip 'static from worker definition. * Strip serde from message definition. * Update example. * Initial Implementation of Reactor Worker. * Implement Spawner and Registrar. * Rename Receiver to Source. * Allow any stream. * Split bridge into receiver and sender. * Add docs. * Add oneshot macro. * Add reactor macro. * Allows synchronous function for oneshot worker. * Move to Sink. * Adjust design of reactor worker. * Update reactor macro. * Adjust oneshot signature. * Fix Actor Worker. * Make a reactor example. * Switch to send. * Minor adjustments. * Add some tests. * Update implementation. * Fix CI. * Skip macros in browser tests. * Adjust implementation. * (some) documentation * add tests for prime example * cargo fmt * update CI * fix macro tests * syn 2 * fix typo * Update crates/worker-macros/src/worker_fn.rs Co-authored-by: Kaede Hoshikawa <futursolo@users.noreply.github.com> * temp: disable chrome in workers CI * disable prime example in CI the example crashes only in CI for some reason --------- Co-authored-by: Muhammad Hamza <muhammadhamza1311@gmail.com>
- Loading branch information
Showing
60 changed files
with
2,102 additions
and
253 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
[package] | ||
name = "gloo-worker-macros" | ||
version = "0.1.0" | ||
authors = ["Rust and WebAssembly Working Group"] | ||
edition = "2021" | ||
readme = "README.md" | ||
description = "Convenience crate for working with Web Workers" | ||
repository = "https://github.com/rustwasm/gloo/tree/master/crates/worker" | ||
homepage = "https://github.com/rustwasm/gloo" | ||
license = "MIT OR Apache-2.0" | ||
categories = ["api-bindings", "asynchronous", "wasm"] | ||
|
||
[lib] | ||
proc-macro = true | ||
|
||
[dependencies] | ||
proc-macro-crate = "1.2.1" | ||
proc-macro2 = "1.0.47" | ||
quote = "1.0.21" | ||
syn = { version = "2.0.15", features = ["full"] } | ||
|
||
[dev-dependencies] | ||
trybuild = "1" | ||
gloo = { path = "../..", features = ["futures"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<div align="center"> | ||
|
||
<h1><code>gloo-worker</code></h1> | ||
|
||
<p> | ||
<a href="https://crates.io/crates/gloo-worker"><img src="https://img.shields.io/crates/v/gloo-worker.svg?style=flat-square" alt="Crates.io version" /></a> | ||
<a href="https://crates.io/crates/gloo-worker"><img src="https://img.shields.io/crates/d/gloo-worker.svg?style=flat-square" alt="Download" /></a> | ||
<a href="https://docs.rs/gloo-worker"><img src="https://img.shields.io/badge/docs-latest-blue.svg?style=flat-square" alt="docs.rs docs" /></a> | ||
</p> | ||
|
||
<h3> | ||
<a href="https://docs.rs/gloo-worker">API Docs</a> | ||
<span> | </span> | ||
<a href="https://github.com/rustwasm/gloo/blob/master/CONTRIBUTING.md">Contributing</a> | ||
<span> | </span> | ||
<a href="https://discordapp.com/channels/442252698964721669/443151097398296587">Chat</a> | ||
</h3> | ||
|
||
<sub>Built with 🦀🕸 by <a href="https://rustwasm.github.io/">The Rust and WebAssembly Working Group</a></sub> | ||
</div> | ||
|
||
Gloo workers are a way to offload tasks to web workers. These are run concurrently using | ||
[web-workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers). | ||
It provides a neat abstraction over the browser's Web Workers API which can be consumed from anywhere. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
use proc_macro::TokenStream; | ||
use syn::parse_macro_input; | ||
|
||
mod oneshot; | ||
mod reactor; | ||
mod worker_fn; | ||
|
||
use oneshot::{oneshot_impl, OneshotFn}; | ||
use reactor::{reactor_impl, ReactorFn}; | ||
use worker_fn::{WorkerFn, WorkerName}; | ||
|
||
#[proc_macro_attribute] | ||
pub fn reactor(attr: TokenStream, item: TokenStream) -> TokenStream { | ||
let item = parse_macro_input!(item as WorkerFn<ReactorFn>); | ||
let attr = parse_macro_input!(attr as WorkerName); | ||
|
||
reactor_impl(attr, item) | ||
.unwrap_or_else(|err| err.to_compile_error()) | ||
.into() | ||
} | ||
|
||
#[proc_macro_attribute] | ||
pub fn oneshot(attr: TokenStream, item: TokenStream) -> TokenStream { | ||
let item = parse_macro_input!(item as WorkerFn<OneshotFn>); | ||
let attr = parse_macro_input!(attr as WorkerName); | ||
|
||
oneshot_impl(attr, item) | ||
.unwrap_or_else(|err| err.to_compile_error()) | ||
.into() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
use proc_macro2::{Span, TokenStream}; | ||
use quote::quote; | ||
use syn::{parse_quote, Ident, ReturnType, Signature, Type}; | ||
|
||
use crate::worker_fn::{WorkerFn, WorkerFnType, WorkerName}; | ||
|
||
pub struct OneshotFn {} | ||
|
||
impl WorkerFnType for OneshotFn { | ||
type OutputType = Type; | ||
type RecvType = Type; | ||
|
||
fn attr_name() -> &'static str { | ||
"oneshot" | ||
} | ||
|
||
fn worker_type_name() -> &'static str { | ||
"oneshot" | ||
} | ||
|
||
fn parse_recv_type(sig: &Signature) -> syn::Result<Self::RecvType> { | ||
let mut inputs = sig.inputs.iter(); | ||
let arg = inputs | ||
.next() | ||
.ok_or_else(|| syn::Error::new_spanned(&sig.ident, "expected 1 argument"))?; | ||
|
||
let ty = Self::extract_fn_arg_type(arg)?; | ||
|
||
Self::assert_no_left_argument(inputs, 1)?; | ||
|
||
Ok(ty) | ||
} | ||
|
||
fn parse_output_type(sig: &Signature) -> syn::Result<Self::OutputType> { | ||
let ty = match &sig.output { | ||
ReturnType::Default => { | ||
parse_quote! { () } | ||
} | ||
ReturnType::Type(_, ty) => *ty.clone(), | ||
}; | ||
|
||
Ok(ty) | ||
} | ||
} | ||
|
||
pub fn oneshot_impl( | ||
name: WorkerName, | ||
mut worker_fn: WorkerFn<OneshotFn>, | ||
) -> syn::Result<TokenStream> { | ||
worker_fn.merge_worker_name(name)?; | ||
|
||
let struct_attrs = worker_fn.filter_attrs_for_worker_struct(); | ||
let oneshot_impl_attrs = worker_fn.filter_attrs_for_worker_impl(); | ||
let phantom_generics = worker_fn.phantom_generics(); | ||
let oneshot_name = worker_fn.worker_name(); | ||
let fn_name = worker_fn.inner_fn_ident(); | ||
let inner_fn = worker_fn.print_inner_fn(); | ||
|
||
let WorkerFn { | ||
recv_type: input_type, | ||
generics, | ||
output_type, | ||
vis, | ||
is_async, | ||
.. | ||
} = worker_fn; | ||
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); | ||
let fn_generics = ty_generics.as_turbofish(); | ||
|
||
let in_ident = Ident::new("_input", Span::mixed_site()); | ||
|
||
let fn_call = if is_async { | ||
quote! { #fn_name #fn_generics (#in_ident).await } | ||
} else { | ||
quote! { #fn_name #fn_generics (#in_ident) } | ||
}; | ||
let crate_name = WorkerFn::<OneshotFn>::worker_crate_name(); | ||
|
||
let quoted = quote! { | ||
#(#struct_attrs)* | ||
#[allow(unused_parens)] | ||
#vis struct #oneshot_name #generics #where_clause { | ||
inner: ::std::pin::Pin<::std::boxed::Box<dyn ::std::future::Future<Output = #output_type>>>, | ||
_marker: ::std::marker::PhantomData<(#phantom_generics)>, | ||
} | ||
|
||
// we cannot disable any lints here because it will be applied to the function body | ||
// as well. | ||
#(#oneshot_impl_attrs)* | ||
impl #impl_generics ::#crate_name::oneshot::Oneshot for #oneshot_name #ty_generics #where_clause { | ||
type Input = #input_type; | ||
|
||
fn create(#in_ident: Self::Input) -> Self { | ||
#inner_fn | ||
|
||
Self { | ||
inner: ::std::boxed::Box::pin( | ||
async move { | ||
#fn_call | ||
} | ||
), | ||
_marker: ::std::marker::PhantomData, | ||
} | ||
} | ||
} | ||
|
||
impl #impl_generics ::std::future::Future for #oneshot_name #ty_generics #where_clause { | ||
type Output = #output_type; | ||
|
||
fn poll(mut self: ::std::pin::Pin<&mut Self>, cx: &mut ::std::task::Context<'_>) -> ::std::task::Poll<Self::Output> { | ||
::std::future::Future::poll(::std::pin::Pin::new(&mut self.inner), cx) | ||
} | ||
} | ||
|
||
impl #impl_generics ::#crate_name::Registrable for #oneshot_name #ty_generics #where_clause { | ||
type Registrar = ::#crate_name::oneshot::OneshotRegistrar<Self>; | ||
|
||
fn registrar() -> Self::Registrar { | ||
::#crate_name::oneshot::OneshotRegistrar::<Self>::new() | ||
} | ||
} | ||
|
||
impl #impl_generics ::#crate_name::Spawnable for #oneshot_name #ty_generics #where_clause { | ||
type Spawner = ::#crate_name::oneshot::OneshotSpawner<Self>; | ||
|
||
fn spawner() -> Self::Spawner { | ||
::#crate_name::oneshot::OneshotSpawner::<Self>::new() | ||
} | ||
} | ||
}; | ||
|
||
Ok(quoted) | ||
} |
Oops, something went wrong.