mise icon indicating copy to clipboard operation
mise copied to clipboard

fix: stuck mise with flag --verbose

Open roele opened this issue 1 year ago • 10 comments

@jdx This is an odd one, i would expect that the env() call in the Debug implementation of Config would already initialize the env but for some reason this leads to described behaviour. If i call env() explicitly before the debug! macro it works as expected. Any idea why that might be?

Resolves #1830

roele avatar Mar 31 '24 11:03 roele

it looks like this broke the python test for some reason. I tried running it again but it failed.

jdx avatar Mar 31 '24 12:03 jdx

It seems the following code (env() and path_dirs()) from impl Debug for Config causes a deadlock. Need to dig deeper to figure out why exactly...

if let Ok(env) = self.env() {
    if !env.is_empty() {
        s.field("Env", &env);
        // s.field("Env Sources", &self.env_sources);
    }
}
let path_dirs = self.path_dirs().cloned().unwrap_or_default();
if !path_dirs.is_empty() {
    s.field("Path Dirs", &path_dirs);
}

roele avatar Mar 31 '24 17:03 roele

So far what i figured out is that OneCell::get_or_try_init is no-reentrant and might cause a deadlock if called recursively. Reworking the code to initialize env seems to mitigate that issue but causes another one related to Python.

After some fiddling with the ./e2e/test_python, it seems that the line venv = {path = "{{env.MISE_DATA_DIR}}/venv", create=true} is causing the stack overflow.

roele avatar Apr 01 '24 14:04 roele

@jdx I assume the following code resembles a global singleton pattern in Rust?

pub fn try_get() -> Result<Arc<Self>> {
    if let Some(config) = &*CONFIG.read().unwrap() {
        return Ok(config.clone());
    }
    let config = Arc::new(Self::load()?);
    *CONFIG.write().unwrap() = Some(config.clone());
    Ok(config)
}

It seems that this does not work as intended when the EnvDirective::PythonVenv does call Config::get(). So Config uses EnvDirective on initialization (load_env()) to resolve the environment but also relies on Config to create a venv. This causes the reentrant behaviour on OnceCell and when mitigated a stackoverflow due to endless load_env() calls.

roele avatar Apr 01 '24 16:04 roele

@jdx I assume the following code resembles a global singleton pattern in Rust?

yeah, I'm not using Lazy here because in the unit tests I need the ability to clear the value in a single process. It seems I recognized this was an issue when I wrote it: https://github.com/jdx/mise/blob/a8ac6cdca6d3322b6d406fa32d27c89ec488a9ee/src/config/env_directive.rs#L167

I'm not sure what to do here. We have a high-level paradox: env loading happens before we load the tools, but we need to load the tools so we know which python version to load.

One thought is perhaps we could perform venv creation at the end of loading mise after the tools are loaded, but if we did that we'd then need a way to rerun the env to load a brand new one. Another thought is maybe we could just load python if it is defined, but that might not be very easy to accomplish.

jdx avatar Apr 02 '24 00:04 jdx

I also don't see a straight forward solution right now.

What could be done as a workaround is simply comment out the entire debug! macro or the parts (Env, Path Dirs) of the impl Debug for Config causing the deadlock.

roele avatar Apr 06 '24 09:04 roele

converted to draft until one of us figures out a better solution here

jdx avatar Apr 06 '24 16:04 jdx

where is this debug call? could we just only show the env if it is already loaded?

jdx avatar Apr 06 '24 17:04 jdx

The debug! call causing this is at https://github.com/jdx/mise/blob/main/src/config/mod.rs#L94.

Loading the env involves env_directive which uses Config::get() which causes a circular dependency potentially leading to a stack overflow.

roele avatar Apr 06 '24 17:04 roele

I'm thinking we change this conditional: https://github.com/jdx/mise/blob/2738afd45afdf9864a3badda13d8d1075f5a30bd/src/config/mod.rs#L606

instead of calling self.env() we call self.env_with_sources.get()

I think the loading order is still problematic, but this could get us around this specific issue at least.

jdx avatar Apr 06 '24 17:04 jdx

I fixed this issue today

jdx avatar May 14 '24 04:05 jdx