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

REPL: generate tab completion hints on a worker thread to not block typing #57192

Merged

Conversation

IanButterworth
Copy link
Member

@IanButterworth IanButterworth commented Jan 29, 2025

Prevents slow tab completion hint generation from blocking typing.

Fixes #55434
Specifically the hinting part.

With julia now starting with an interactive thread by default, we can move the repl tab completion hint generation to a worker thread and enable the user to continue to type (on the repl task on the interactive thread) if generating the hint takes a long time. Showing old hints is cancelled if a new key has been pressed since.

Take this intentionally slowly compiling generated function, which needs to be generated to be introspected for completions. (thanks @MasonProtter for the example)

@generated function foo()
    sleep(5)
    (;apple=1, banana=2)
end

On master and 1.11 typing is blocked at foo(). while the generated function compiles for 5s.

On this PR typing can continue and at any point the user can wait 5s for apple to be completed properly.

Screen.Recording.2025-01-28.at.10.30.27.PM.mov

@IanButterworth IanButterworth added the REPL Julia's REPL (Read Eval Print Loop) label Jan 29, 2025
@IanButterworth IanButterworth added this to the 1.12 milestone Jan 29, 2025
@IanButterworth IanButterworth force-pushed the ib/repl_hint_threaded branch 2 times, most recently from 61d0213 to 5b8b07b Compare January 29, 2025 21:34
@IanButterworth
Copy link
Member Author

IanButterworth commented Jan 29, 2025

One thing I don't understand is that a sleep acts differently to a busywait

With a busywait, the behavior is as expected. After typing foo() and continuing to type .app slowly, the completion appears after 5s from when the . was pressed.

julia> using StressTest

julia> @generated function foo()
           busywait(5)
           (;apple=1, banana=2)
       end;

julia> foo().apple

With a sleep every keypress in .app resets the 5s timer.

julia> @generated function foo()
           sleep(5)
           (;apple=1, banana=2)
       end;

julia> foo().apple

Looking at internals, this line returns earlier than 5s if a key is pressed, which it doesn't do for busywait

Base.invoke_in_world(COMPLETION_WORLD[], CC.typeinf, interp, frame)

Is there already some cancellation on keypress behavior in REPLInterpreter? Or is it some IO bug with stdin and the timer?

@IanButterworth

This comment has been minimized.

@IanButterworth
Copy link
Member Author

This is an important improvement to get into 1.12, and I think this is in good shape now to be tried out in the wild, so I will merge. Post-merge review would of course be appreciated.

@IanButterworth IanButterworth merged commit 0b9525b into JuliaLang:master Jan 31, 2025
7 checks passed
@IanButterworth IanButterworth deleted the ib/repl_hint_threaded branch January 31, 2025 17:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
REPL Julia's REPL (Read Eval Print Loop)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

REPL hints and tab completion freezes the REPL
1 participant