Skip to content

Fix race condition potentially overwriting user configuration#4642

Open
PatrickHaecker wants to merge 1 commit intoJuliaLang:masterfrom
PatrickHaecker:patch-2
Open

Fix race condition potentially overwriting user configuration#4642
PatrickHaecker wants to merge 1 commit intoJuliaLang:masterfrom
PatrickHaecker:patch-2

Conversation

@PatrickHaecker
Copy link
Copy Markdown

If the user set, e.g.,

atreplinit() do repl
    # Robust against older julia versions
    if hasfield(typeof(repl.options), :auto_insert_closing_bracket)
        repl.options.auto_insert_closing_bracket = false
    end
end

in their startup.jl it has no effect in VS Code's REPL due to VS Code's plugin loading Pkg.jl which is calling REPL.setup_interface(repl) inside an atreplinit hook, which bakes keymaps before user options are applied. The proper approach is to let run_frontend handle interface creation and defer mode initialization until the interface exists.

Note, that this fix is necessary, but not sufficient to make it work, because the same race condition needs to be fixed at least in TerminalPager.jl and in julia-vscode.

I used Claude Opus 4.6 while developing this fix.

If the user set, e.g.,
```julia
atreplinit() do repl
    # Robust against older julia versions
    if hasfield(typeof(repl.options), :auto_insert_closing_bracket)
        repl.options.auto_insert_closing_bracket = false
    end
end
```
in their `startup.jl` it has no effect in VS Code's REPL due to VS Code's plugin loading `Pkg.jl` which is calling `REPL.setup_interface(repl)` inside an `atreplinit` hook, which bakes keymaps before user options are applied. The proper approach is to let `run_frontend` handle interface creation and defer mode initialization until the interface exists.

Note, that this fix is necessary, but not sufficient to make it work, because the same race condition needs to be fixed at least in [TerminalPager.jl](ronisbr/TerminalPager.jl#83) and in [julia-vscode](julia-vscode/julia-vscode#4063).

I used Claude Opus 4.6 while developing this fix.
# Do not call `REPL.setup_interface` here — it will be called
# by `run_frontend`, which respects user options set in other
# `atreplinit` hooks (e.g. `auto_insert_closing_bracket`).
@async begin
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel there should be some way to register something to run once the interface is created o something like that, instead of needing a sleep loop like this.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fully agree. This PR is in the spirit of "at least make it work correctly" not in the spirit of "this is how the optimum solution should look like".

When I implemented this pattern for TerminalPager.jl, I did some analysis on my average notebook and typically it did not sleep at all during a regular REPL start, so it was more of a "if things are unusual still make them work correctly" thing. I haven't done any timing analysis on the Pkg.jl race condition, but I was reliably able to reproduce the problem when starting the REPL in VS Code, so I'd expect it to sleep at least once on my computer in this use case.

As much as I want to have the registration interface, I guess this would need to come earliest with Julia 1.14 and would need to tickle down until it hits the long term supported Julia release until we can get rid of this sleep loop.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is related JuliaLang/julia#54890

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand all relevant code well enough to state whether JuliaLang/julia#54890 will fix this, but given that we have a synchronization problem here, a synchronization mechanism where only one user at a time gets access to a lock with the REPL guaranteed to get access initially seems to solve the problem.

However, I suggest to not let the perfect be the enemy of the good. Starting with Julia 1.13, we recommend a way which is broken by the current implementation of Pkg.jl, so the REPL in a regular terminal behaves differently (if PKG is not loaded on startup) than the VS Code terminal which is quite annoying.

We can change the sleep time and/or we can progressively increase the sleep time if you want to be sure that the unnecessary relative wait time is limited, but I think we should implement something close to the current PR in Pkg now and then everyone is invited to improve on it in and for 1.14 onward.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: New

Development

Successfully merging this pull request may close these issues.

3 participants