-
Notifications
You must be signed in to change notification settings - Fork 176
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
zenoh::open crashes in single threaded environment #835
Comments
Created a few more tests - the first one succeeds the latter two not:
|
@YuanYuYuan would you mind performing some additional test on this issue? |
I'm still studying a perfect solution to it. Try to summarise what I know so far.
fn main() {
let rt1 = Builder::new_multi_thread().enable_all().build().unwrap();
rt1.block_on(async {
let rt2 = Builder::new_multi_thread().enable_all().build().unwrap();
rt2.block_on(async {
println!("Done");
})
});
} Cannot start a runtime from within a runtime. This happens because a function (like `block_on`) attempted to block the current thread while the thread is being used to drive asynchronous tasks. To work around it, we wrap the fn main() {
let rt1 = Builder::new_multi_thread().enable_all().build().unwrap();
rt1.block_on(async {
let rt2 = Builder::new_multi_thread().enable_all().build().unwrap();
tokio::task::block_in_place(move ||
rt2.block_on(async {
println!("Done");
})
)
});
} This lets us fn main() {
let rt1 = Builder::new_multi_thread().enable_all().build().unwrap();
rt1.block_on(async {
std::thread::spawn(|| {
let rt2 = Builder::new_multi_thread().enable_all().build().unwrap();
rt2.block_on(async {
println!("Done");
})
})
.join()
.unwrap();
});
}
fn main() {
Builder::new_current_thread().enable_all().build().unwrap().block_on(async { ... });
} and fn main() {
Builder::new_multi_thread().enable_all().build().unwrap().block_on(async { ... });
} The issue @stepkun reported here is tokio restricts fn main() {
let rt1 = Builder::new_current_thread().enable_all().build().unwrap(); // <-- current thread scheduler
rt1.block_on(async {
let rt2 = Builder::new_multi_thread().enable_all().build().unwrap();
tokio::task::block_in_place(move || // <-- error
rt2.block_on(async {
println!("Done");
})
)
});
} can call blocking only when running on the multi-threaded runtime Although we can use fn main() {
let rt1 = Builder::new_current_thread().enable_all().build().unwrap();
rt1.block_on(async {
std::thread::spawn(|| {
let rt2 = Builder::new_multi_thread().enable_all().build().unwrap();
rt2.block_on(async {
println!("Done");
})
})
.join()
.unwrap();
});
} it's not easy to adopt this solution since
#[async_std::main]
async fn main() {
let rt = Builder::new_multi_thread().enable_all().build().unwrap();
tokio::task::block_in_place(move ||
rt.block_on(async {
println!("Done");
})
)
}
fn main() {
let rt = Builder::new_multi_thread().enable_all().build().unwrap();
tokio::task::block_in_place(move ||
rt.block_on(async {
println!("Done");
})
)
} Furthermore, users still can call zenoh from a single threaded environment #[tokio::main(flavor = "multi_thread", worker_threads = 1)] // Use one single thread to call zenoh (and process maybe other stuffs)
async fn main() {
let rt = Builder::new_multi_thread()
.thread_name("ZRuntime")
.enable_all()
.build()
.unwrap();
tokio::task::block_in_place(move || {
rt.block_on(async {
tokio::time::sleep(std::time::Duration::from_secs(10000)).await;
println!("Done");
})
})
} PID User │ TTY CPU MEM TCP CPU Time │ Command
│ [%] [%] │
└┬─────── 1 root │ 0.0 0.1 00:00:04 │ /sbin/init
└┬────── 6172 user │ 0.0 0.1 [] 00:31:44 │ tmux attach-session
└┬───── 2420082 user │ pts/3 0.0 0.0 [] 00:00:05 │ -zsh
└┬──── 3442553 user │ pts/3 0.0 0.0 [] 00:00:00 │ target/debug/tokio-dev
├──── [3442664] user │ pts/3 0.0 0.0 00:00:00 │ tokio-runtime-w // The so-called single threaded environment
├──── [3442665] user │ pts/3 0.0 0.0 00:00:00 │ ZRuntime // ZRuntimes are used internally
├──── [3442666] user │ pts/3 0.0 0.0 00:00:00 │ ZRuntime
├──── [3442667] user │ pts/3 0.0 0.0 00:00:00 │ ZRuntime
├──── [3442668] user │ pts/3 0.0 0.0 00:00:00 │ ZRuntime
├──── [3442669] user │ pts/3 0.0 0.0 00:00:00 │ ZRuntime
├──── [3442670] user │ pts/3 0.0 0.0 00:00:00 │ ZRuntime
├──── [3442671] user │ pts/3 0.0 0.0 00:00:00 │ ZRuntime
└──── [3442672] user │ pts/3 0.0 0.0 00:00:00 │ ZRuntime There might be confusion between the single-threaded environment/runtime and tokio's current thread scheduler. Actually we still can use single-threaded runtime with a multi thread scheduler. On the other hand, the current thread scheduler is designed for single thread and any blocking on it should be careful. As a quick fix to this issue, we may forbid the calling of zenoh from a current thread scheduler. And a long term solution is to remove the unsoundness of nested *Bonus: I found that an additional fn main() {
let rt1 = Builder::new_current_thread().enable_all().build().unwrap();
rt1.handle().block_on(async {
let rt2 = Builder::new_multi_thread().enable_all().build().unwrap();
tokio::task::block_in_place(move ||
rt2.block_on(async {
println!("Done");
})
)
});
} @stepkun, thanks for reporting the issue and any comment is welcome! |
I also only found possible solutions using (hidden) handles. fn main() {
let rt1 = Builder::new_current_thread().enable_all().build().unwrap();
rt1.block_on(async move {
let _r = tokio::task::spawn(async {
println!("Done");
}).await;
});
} Or this, if a non async closure is needed: fn main() {
let rt1 = Builder::new_current_thread().enable_all().build().unwrap();
rt1.block_on(async {
let _r = tokio::task::spawn_blocking(move || {
println!("Done");
}).await;
});
} credits to: Alice Rhyl |
Yes, we have studied Alice's post before. Unfortunately, |
Yes that is inevitable. |
BTW, I just found that both |
We do have the same experience a few months ago. Feel free to contact us if you have any issues. You can either open an issue or leave a message in Discord. 😃 According to Alice's words, async-std tends to process this problematic stuff silently. It may be a good procedure to inform users of the risk beforehand. |
Thank you. |
Describe the bug
With current main branch (#c401e3a( zenoh seem not to work anymore in a single threaded tokio environment. It worked with #ba50eec
To reproduce
can be produced with
will panic with something like
System info
Plattform; ubuntu 22.04 on Intel i7 gen 4
The text was updated successfully, but these errors were encountered: