-
-
Notifications
You must be signed in to change notification settings - Fork 89
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
Fix kpsewhich
timeout on Windows using Tex Live Full
#3727
Conversation
Setting this to draft to add a fix for |
6331b8d
to
e86319f
Compare
e86319f
to
0a84252
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for the refactor! This is a great improvement I think.
Change parameter nonBlocking of (former) SystemEnvironmentKt.runCommandWithExitCode() to discardOutput.
Yeah that's fine, I think the parameter was just there to prevent issues with things getting stuck waiting for output that was not necessary
* @param returnExceptionMessageAsErrorOutput Whether to return exception messages as error output if exceptions are thrown. | ||
* @param timeout The timeout for execution. Does not stop reading the process' output as long as it is available. | ||
*/ | ||
suspend fun runCommandNonBlocking( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but I don't know how nl.hannahsten.texifyidea.util.files.LatexPackageLocationCache#getPackageLocation() is called.
If I remove LatexPackageLocationCacheInitializer then it doesn't appear to be blocking the UI, at least it's running in a background thread.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea on how to test this.
Sadly I was now able to provoke a freezed UI. Steps to reproduce:
- Disable
LatexPackageLocationCacheInitializer
. - Add to document following content
\documentclass{report}
\begin{document}
\end{document}
- Edit the file.
To make the effect more obvious, replace runBlocking { fillCacheWithKpsewhich(project) }
with runBlocking { delay(1_000) }
.
I can try to move the execution in another thread, but if this works depends on where the freezing occurs. Maybe another option is just to remove this call to fillCacheWithKpsewhich()
as the cache should be filled at startup and getPackageLocation()
is called multiple times - at least if it returns null
. In either case I probably won't be able to evaluate this before next weekend.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, that does block the UI. But I don't understand, why is the UI not blocked if I put there runBlocking { runCommandNonBlocking("sleep", "3") }
to simulate a long-running command?
I'm also not quite sure why the UI is blocked if we run runBlocking { delay(1_000) }
in a background thread. Documentation: https://plugins.jetbrains.com/docs/intellij/threading-model.html#avoiding-ui-freezes
It's true that for this particular case we can maybe circumvent the issue, but there are other places where we are running system calls and need to wait for the result to return it to IntelliJ api, and I don't know how to do that without blocking the thread (and thus the UI, apparently?). Another example is LatexDocumentationProvider, which can be triggered in the autocompletion popup. (If I put a delay in runCommandWithExitCode then UI will block)
In any case, that is out of scope for this PR, so I'll merge this already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you make sure the command is executed? I had to circumvent the if-clause to test this:
if (true || cache == null) {
runBlocking {
runCommandNonBlocking("ping", "-n", "30", "127.0.0.1", discardOutput = true)
}
}
With this I was able to block the UI until timeout.
As to why it blocks the UI, I'm not really sure as the debugger implies that those are indeed run in separate threads.
Add function `runCommandNonBlocking()` to run shell commands in a non-blocking way and refactor `runCommand()` and `runCommandWithExitCode()` to use the newly created function. Additionally, add parameter `timestamp` to function `runCommand()`. Breaking changes: * Renamed parameter `nonBlocking` to `discardOutput` in `runCommandWithExitCode()`.
Increase timeout for kpsewhich path expansion to prevent LatexPackageLocationCache being empty. Additionally, make `fillCacheWithKpsewhich()` a suspend function, use non-blocking shell command execution and add logging to analyze number of paths loaded into LatexPackageLocationCache. See !3653 for details and measurements.
Additionally, update usages of `String.runCommand()` in suspending functions to use `String.runCommandNonBlocking()`.
55dcc13
to
c956459
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, thanks a lot! I learned some things about coroutines again.
Fix #3653
Summary of additions and changes
CommandRunnerKt.runCommandNonBlocking()
and refactorSystemEnvironmentKt.runCommand()
andSystemEnvironmentKt.runCommandWithExitCode()
to use it as their base. The main differences are:nonBlocking
of (former)SystemEnvironmentKt.runCommandWithExitCode()
todiscardOutput
. The intent of users of this parameter seems to be to just don't care about the commands output, so this change seems to be safe. Also the implementation of the former behavior is not easy with the added asynchronous contexts for reading the streams.kpsewhich
path expansion to 10 seconds to allow it to return and added logging of number of paths loaded. (I did not add a check only to increase the timeout on Windows, as is does not seem to block the IDE.)String.runCommandNonBlocking()
and replace usages ofString.runCommand()
in suspending functions.I'm not quite sure if it runs in the background. The caller
nl.hannahsten.texifyidea.startup.LatexPackageLocationCacheInitializer#execute()
seems to run it in the background but I don't know hownl.hannahsten.texifyidea.util.files.LatexPackageLocationCache#getPackageLocation()
is called. The former I could not provoke a hanging UI with, even with added delays. The latter I could not provoke a call to without having the cache filled first, so I could not check if it runs in background.How to test this pull request
Verify the following document does not show error
File 'article.cls' not found
: