Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create an API to retrieve the HandlerId of a Worker from its WorkerBridge #241

Open
mathias-vandaele opened this issue Aug 9, 2022 · 7 comments

Comments

@mathias-vandaele
Copy link

Summary

A user should be able to retrieve the HandlerId of a worker from its unique Bridge.

Motivation

Some Application potentially spawns many workers and needs to store a lot of Bridge within a HashMap; we could keep track of which Bridge is linked to which worker if that was implemented.

Detailed Explanation

We could develop an API to get the ID from the bridge.

                let starting_worker = self.worker_spawner.callback({
                    let link = ctx.link().clone();
                    move |e| link.send_message(Msg::WorkerMsg(e))
                }).spawn("/calculator.js");
                starting_worker.send(());
                self.workers.insert(starting_worker.handler_id(), starting_worker);

Drawbacks, Rationale, and Alternatives

I propose this design cause I believe it has not been thought of. I might be wrong; there might be another solution to retrieve the id, which I have not found.

The function would return usize.
I'm open to discussion if there are any drawbacks I am unaware of. For now, I don't think returning a usize could be an issue.

Unresolved Questions

N/A

@hamza1311
Copy link
Collaborator

Pinging @futursolo for their feedback

@futursolo
Copy link
Collaborator

futursolo commented Aug 11, 2022

You should be able to do this with AnyMap.

let mut workers = anymap::AnyMap::new();

let worker = CalculatorWorker::spawner().spawn("/calculator.js");
workers.insert(worker);

workers.get::<WorkerBridge<CalculatorWorker>>().expect("failed to get worker");

@mathias-vandaele
Copy link
Author

There should be a convenient way to retrieve it.

I have seen in the markdown example that the handler_id is sent back in the output message.

#[derive(Debug)]
pub enum Msg<T> {
    Respond { output: T, id: HandlerId },
}

Why do this if there is no way to make it match with a worker bridge?

If you find this modification pertinent, I would be happy to develop it as my first contribution to the project!

@futursolo
Copy link
Collaborator

futursolo commented Aug 18, 2022

I have seen in the markdown example that the handler_id is sent back in the output message.

This is internal message for the worker itself. The output type is String.
The message is actually not needed in the example. It's there to demonstrate the usage of message.

https://github.com/rustwasm/gloo/blob/master/examples/markdown/src/lib.rs#L19

I propose this design cause I believe it has not been thought of. I might be wrong; there might be another solution to retrieve the id, which I have not found.

The function would return usize.
I'm open to discussion if there are any drawbacks I am unaware of. For now, I don't think returning a usize could be an issue.

Reasons not to expose HandlerId on bridges:

  1. It is not guaranteed to be globally unique.
    We currently provide no guarantee to HandlerIds other than it can be used to distinguish bridges by a worker.
  2. We may not assign a single usize as HandlerId if we were to expand workers to shared workers and service workers.
    (It could be a (MessageChannelId, BridgeId) tuple.)

I don't think it's a widely used practice to use ID-based APIs in Rust.
In rare occasion, when an ID is exposed, it is exposed as an opaque type and does not give access to the underlying usize.

https://doc.rust-lang.org/std/any/struct.TypeId.html

Personally, I would not like to see HandlerIds being exposed on the bridge side.
However, if there is a legitimate use case where an identifier cannot be given to bridges based on AnyMap or enum variants, it should be exposed as an opaque type like std::any::TypeId or tokio::task::Id and not usize.

I will leave the final decision to @hamza1311 .

@hamza1311
Copy link
Collaborator

I agree with not exposing the Id directly. If there's a need to expose the id, it can/should be done through an opaque type. If we were to change how the id is stored, it shouldn't be a breaking change.

I haven't had to use this crate myself so I can't comment on the need of it. I'd be happy to merge any PRs related to this. @futursolo, you can make the decision on if this should be added or not.

@mathias-vandaele
Copy link
Author

Just for the sake of the example:

When managing a bunch of workers, all are spawned to realize a specific task.
When the worker finishes his work, he must respond.

That would be very convenient if I could respond HandlerId as an Output, so I would know which bridge I can drop.

I would rather trust you with design patterns, being very new in the rust community.

@futursolo, feel free to close the issue

@futursolo
Copy link
Collaborator

When the worker finishes his work, he must respond.
That would be very convenient if I could respond HandlerId as an Output, so I would know which bridge I can drop.

I have created a proposal #251 to introduce functional workers that can run asynchronous tasks without them being identified by HandlerIds or WorkerBridges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants