Closed Sherlock-Holo closed 4 years ago
Generally it's best to avoid this kind of thing, but it sounds like block_in_place
does what you're looking for?
Alternatively consider spawning a task and immediately returning from drop()
.
@Darksonn However block_in_place
only can run sync codes, not async codes. I need to run async codes but blocking thread like sync codes.
drop only have &mut self
, it is so hard to spawn a task
You could still use futures::executor::block_on
inside block_in_place
? That will tell Tokio that the current thread will be blocked.
As for spawning inside drop
, you can still use tokio::spawn
if it was dropped inside an async fn. If you wish to detect whether you're inside an async fn, you can use Handle::try_current
and just call spawn on the handle, and otherwise you're outside of async land, so you can just block?
block_in_place
must in a spawned task so I can't do this.
tokio::spawn
need future is Send
, but it's so hard to move something from a &mut self
, perhaps I can use Option
and take()
, then move in async block, but it will changes a lot of codes.
Generally long-running things in destructors are a bad idea. If at all possible, try to find a different solution. As for your spawned future, yes you will likely need an Option
with take()
to go that route.
What confusing me is why tokio doesn't provide like async_std::task::block_on
. I think runtime just need to mark this thread is blocking
and remove it from async thread pool. Is there anything make it hard to do it?
That's what futures::executor::block_on
inside block_in_place
does.
@Darksonn
we can't use block_in_place
in drop directly, like example it will panic with
thread 'main' panicked at 'can call blocking only when running in a spawned task', src/libcore/option.rs:1188:5.
Perhaps I misunderstand what you means? If you cloud give me an example codes I am very grateful
Apparently you can't block inside the "main task" of Tokio. There isn't really much you can do about that, except just blocking and hoping the impact on the scheduler is not too bad.
Yes, so if we want to do this job beautiful and simple, in my option, we still need an api like async_std::task::block_on
.
actually I have tried mix async_std
and tokio
, most codes use async_std
api, of couse used async_std::task::block_on
, then create a tokio runtime and block it by futures::future::pending
to start tokio reactor because I used tonic
, but it make codes so chaos and so hard to maintaining
I don't know why block_in_place
doesn't work in the main task, but I don't think there needs to be a beautiful and simple way to block inside destructors. I recommend trying to get tokio::spawn
to work.
you are right, blocking in destructors is a bad idea, we should try to avoid this.
In other places I need to do a async job in a normal method such as codes, for now it may block some futures which are dispatch to this thread. This method only run once so it may won't cause big problems, but if have an api async_std::task::block_on
, it may solve some problems in the future
I mean generally you shouldn't call blocking code from async function. Perhaps your normal function should be async, or at least have an async counterpart?
I think make the normal function have an async version is the best way, this will reduce a lot of problems 🤣. For now I have to use futures::executor::block_on
to do this job, in the future this function should have an async version or I fork and modify it :-)
I don't know why
block_in_place
doesn't work in the main task, but I don't think there needs to be a beautiful and simple way to block inside destructors. I recommend trying to gettokio::spawn
to work.
I believe block_in_place
doesn't work in the main task because it causes the calling worker thread to transition to being a blocking worker and be replaced by a new worker thread. This doesn't work in the main task because the main task is not running on a worker thread. spawn_blocking
should work, though?
Hey @jonhoo, did #2410 enable use of block_in_place
in the main block_on
task?
Yes, it should have!
Version 0.2.13
Platform
Linux SherlockHolo 5.5.7-arch1-1 #1 SMP PREEMPT Sat, 29 Feb 2020 19:06:02 +0000 x86_64 GNU/Linux
Description
Is there a way to wait a
Future
done in a normal function?For example I need to run some async fn in Drop trait, if I create a new Runtime, wil panic and tell me I can't create a runtime in a runtime, for now I have to use
futures::executor::block_on
. But I have no way to tell tokio runtime that "current thread will be blocked for a long time, you shouldn't dispatch future to this thread any more".Is there any tokio api to wait a
Future
done in a normal function, or tell tokio this thread is blocking?