gloo
gloo copied to clipboard
Proposal: Functional Worker
Summary
This implemented was originally implemented in https://github.com/yewstack/yew/pull/2773 for Yew Agent.
I think this can also be provided to gloo-worker
in a framework agnostic fashion (with the exception of SSR).
Motivation
Previously the gloo_worker::Worker
type implements an actor model which can be difficult for beginners.
This issue proposes 2 new worker types:
-
oneshot
: For each input, a single output is produced. -
reactor
: A type of worker that operates receives inputs and produces outputs over a channel pair.
Detailed Explanation
2 Procedural Macros are added:
#[oneshot]
async fn Squared(input: u32) -> u32 {
input.pow(2)
}
#[reactor]
async fn SquaredOnDemand(rx: Receiver<u32>, tx: Sender<u32>) {
while let Some(m) = rx.next().await {
if tx.send(m.pow(2)).is_err() {
break;
}
}
}
2 Spawner types are added as well:
// OneshotBridge
let squared_bridge = Squared::spawner().spawn();
assert_eq!(squared_bridge.run(2).await, 4);
// ReactorBridge
let (squared_tx, squared_rx) = SquaredOnDemand::spawner().spawn();
squared_tx.send(2);
// Schedules shutdown of bridge.
drop(squared_tx);
assert_eq!(squared_rx.next().await, Some(4));
assert_eq!(squared_rx.next().await, None);
Drawbacks, Rationale, and Alternatives
Drawbacks
The procedural macros will use boxed futures until type_alias_impl_trait
becomes stable.
Alternative Design
Functional workers can also be implemented using a method like tower::service_fn
. With this method, functional workers can be produced without boxing or type_alias_impl_trait
.
However, this can cause issues with the current spawning method as workers are identified with a struct type. (The original Agent v2 also uses context providers to identify agents. This method will produce an anonymous type and cannot be used to create context providers.)
Unresolved Questions
- Should we name the functional workers something else other than
oneshot
andreactor
? - Should
gloo_worker::Worker
be renamed to something else to avoid confusion as there will be multiple worker types?