Hacker News new | past | comments | ask | show | jobs | submit login

The problem that I am running into at the moment is that a few things like the rhai Engine aren't Send and I am trying to use them in an async closure. What GPT-4 suggested was creating a tokio Runtime inside the thread and then block_on(). I will try it tomorrow. (This is the first significant Rust project for me.)



The answer here is almost certainly one of these:

1. Fix rhai::Engine so it is Send (if !Send is unintentional)

2. Use tokio::spawn_blocking or normal threads to run the rhai::Engine bits

3. Don't hold the rhai::Engine across an await point.

Which one depends on rhai Engine details and what you want to accomplish.

Doing a block on inside a new thread seems unlikely to do anything useful (unless there's some undisclosed detail that makes it reasonable).

I encourage you to ask about this in the rhai repo in a discussion or issue.


1. Not applicable unless it is absolutely required, and not something I will consider until I have exhausted other options, since there is a reason they have not made it Send already. It will likely be quite complex and enlarge the scope.

2. I am using a normal thread but when I make it async the compiler wants Send.

3. The await point is in code that uses the engine. I am not sure there is another good option, since I need to use an API that has several libraries all of which are async.

The block_on is to allow the tokio Runtime created in that thread to execute/poll it

So, thank you for your input, I will test out the suggestion that I mentioned above, and then maybe look into spawn_blocking if that doesn't work.


That ChatGPT suggestion is dodgy. Tokio is going to complain when you create a runtime while in async runtime, and refuse block_on in an async context.

You can have multiple runtimes, but create them ahead of time, in synchronous main, and keep a Handle to them.

But you probably need: https://docs.rs/tokio/latest/tokio/task/struct.LocalSet.html


> 2. I am using a normal thread but when I make it async the compiler wants Send.

This is likely because you are using the multi-threaded scheduler, which requires futures to be Send, even if you’re running only a single thread. This is because Tokio is based on a “work stealing” runtime, so in “normal” operations, expects the futures themselves to be able to be shuffled around threads where necessary.

For you use case, try running the single threaded executor, additionally try the “local set” executors. These do not require Send as they are statically guaranteed to be confined to the thread they are spawned on. Block on will also work.

Out of curiosity though, how is the interaction with Rhai performed, are you passing around the engine, and executing the code at certain points where applicable? Do you just need certain results from it sometimes? Etc?


Right, GPT-4 explained that much about shuffling. I am trying to do all the interaction with MPSC channels but was still running into issues.

I think I have a lot of good advice to go try now. Thanks.


From the rhai Engine docs: `Currently, Engine is neither Send nor Sync. Use the sync feature to make it Send + Sync.`


According to the documentation[0], enabling the "sync" feature should make the Engine Send+Sync.

From a quick look at the source, it looks like it switches between using Rc/RefCells and Arc/RwLock.

[0] https://docs.rs/rhai/1.16.2/rhai/#enable-special-functionali...


It being !Send means its not safe to be sent lol, that's down to the way they implemented rhai engine not rust. It's just that rust catches that it's not safe to send because of the trait bounds.


You might be able to use the LocalSet (https://docs.rs/tokio/latest/tokio/task/struct.LocalSet.html) to run !Send futures on a single thread.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: