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

Cached tokio runtime after panic #329

Closed
martinitus opened this issue Sep 24, 2023 · 1 comment · Fixed by #330
Closed

Cached tokio runtime after panic #329

martinitus opened this issue Sep 24, 2023 · 1 comment · Fixed by #330

Comments

@martinitus
Copy link
Contributor

martinitus commented Sep 24, 2023

System: windows
evcxr: 0.15.1

With the following init block

:clear
:dep tokio = {version = "1.17.0", features = ["full"]}

executing the following cell twice leads to two different behaviours:

async fn foo() {
    panic!("hello")
}

foo().await

First execution:

thread '' panicked at 'hello', src/lib.rs:3:5
stack backtrace:
note: Some details are omitted, run with RUST_BACKTRACE=full for a verbose backtrace.`

Second execution:

thread '' panicked at 'called Result::unwrap() on an Err value: PoisonError { .. }', src/lib.rs:100:63
stack backtrace:
note: Some details are omitted, run with RUST_BACKTRACE=full for a verbose backtrace.

Obviously, there is nothing one can do about the first error, however, the second error is problematic, as the only way recovering from this seems to be to issue a :clear and dep tokio again. This is "bad", because all other state is also lost.

I assume this PoisonError stems from the mutex on the runtime introduced in #90.

It would be nice if we could either:

  • only clear the cached runtime
  • or in case of a panic in the block_on thread automatically invalidate the cached runtime to create a new one on the next async call.

This should then allow to keep using variables that eventually were created in a different runtime (as long as they are Sync/Send...)??!

Either way, like what you are doing here - if I find some time and you are interested in contributions I might actually give it a shot ;-)

@martinitus
Copy link
Contributor Author

I see two potential solutions:

  • assume that accessing the runtime via the poisoned lock is ok via into_inner in
    if self.state.async_mode {
    user_code = CodeBlock::new()
    .generated(stringify!(evcxr_variable_store
    .lazy_arc("evcxr_tokio_runtime", || std::sync::Mutex::new(
    tokio::runtime::Runtime::new().unwrap()
    ))
    .lock()
    .unwrap()))
    .generated(".block_on(async {")
    .add_all(user_code);
  • Or recreating the runtime. This could work by moving the mutex generation into the lazy_arc method, e.g. one could check if the mutex in the returned arc is poissoned and recreate it in that case.

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

Successfully merging a pull request may close this issue.

1 participant