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

Request: !Send/Sync handlers (IE thread-local handlers) #837

Open
jkelleyrtp opened this issue Jul 14, 2021 · 7 comments
Open

Request: !Send/Sync handlers (IE thread-local handlers) #837

jkelleyrtp opened this issue Jul 14, 2021 · 7 comments
Labels
design Open design question enhancement New feature or request

Comments

@jkelleyrtp
Copy link

I love Tide, but the requirement of Send/Sync on handlers can be an obstacle at times. I believe Actix provides handlers that don't have the send/sync requirement by running them on a per-thread basis. Is there any way to achieve non Send/Sync handlers with Tide?

If there isn't - I'd be interested in figuring out how to add it.

Right now, I'm building a task system outside of the Tide app, and then passing in a channel handler as state, which is a fine pattern, but would be useful if I could just run the !Send futures directly in a handler - since it's very likely that the request will stay on the same thread anyways.

@jbr
Copy link
Member

jbr commented Jul 14, 2021

There is not currently a way to do this, and it would be a large (almost certainly semver-major) change to tide. I've looked into doing this a little bit before and I believe it would either require building our own actix-type !Send scheduler on top of async-executor's executor primitives, or getting async-global-executor (and async-std) to add support for that. If it weren't added to async-global-executor/async-std, we'd need to run two executors.

Probably the best way to go about adding support for this would be adding !Send support to async-global-executor (something like this, maybe?), but that would require interest from that team. Alternatively, tide could run its own flavored runtime like actix runs their own flavor of tokio, but that's a lot of code for tide to take on.

We'd need something like:

spawn_unsend<Fun, Fut>(f: Fun) -> JoinHandle<Fut::Output>
where
    Fun: FnOnce() -> Fut + Send + 'static,
    Fut: Future + 'static,
    Fut::Output: Send + 'static {}

The interesting thing here is that this type of runtime also has a number of different thread allocation (load balancing) strategies, so that might either be configured on the runtime or passed into spawn_unsend, like spawn_unsend(|| async { Rc::new(()) }, Strategy::RoundRobin)

@jbr
Copy link
Member

jbr commented Jul 14, 2021

@yoshuawuyts, @kerupse ☝️

@Fishrock123 Fishrock123 added enhancement New feature or request design Open design question labels Jul 14, 2021
@jbr
Copy link
Member

jbr commented Jul 14, 2021

This is also something I have interest in for my other framework, so I'd also be willing to spend some time helping make this work in async-executor. I did bring it up here but that didn't exactly spark an enthusiastic conversation. I personally believe a non-work-stealing (?Send) async executor is an excellent fit specifically for http servers (not general-purpose async io necessarily), but when I evaluated doing this as part of a framework, I concluded that without buy-in from the async-executor/async-global-executor team, the end-user complexity is not worth the benefit.

@Fishrock123
Copy link
Member

I can't seem to load that discord link FWIW.

@jbr
Copy link
Member

jbr commented Jul 19, 2021

It's in the smol discord so you'd probably have to join that

@jkelleyrtp
Copy link
Author

jkelleyrtp commented Oct 3, 2021

I found this comment by the Actix team particularly interesting - they don't need any changes from Tokio - just spin up a bunch of worker threads, a thread-local executor on each, and then a localset for each thread. The request are still Send, but the user code is !Send, since it's ran in the localset. I imagine a layer could be implemented on top of Tide that does exactly this, but with async_std.

rust-lang/wg-async#87 (comment)

I probably don't want to start my own web framework project just to get !Send web handlers without the Actix approach.

@Fishrock123 Fishrock123 reopened this Oct 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
design Open design question enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants