gloo icon indicating copy to clipboard operation
gloo copied to clipboard

Proposal: Functional Worker

Open futursolo opened this issue 2 years ago • 0 comments

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:

  1. oneshot: For each input, a single output is produced.
  2. 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 and reactor?
  • Should gloo_worker::Worker be renamed to something else to avoid confusion as there will be multiple worker types?

futursolo avatar Sep 04 '22 12:09 futursolo