-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
reader: Fixed race condition #4070
Conversation
was properly initialized. Currently, when reloading input very quickly (happens when updating the prompt quickly with 'reload' bound to 'change') it is possible for the reader's terminate method to be called before readFromCommand properly spawns the new reader process. This means the process is never killed and input is not reloaded until the process completes naturally or another 'EvtSearchNew' is triggered. An example where this becomes a problem is when using fzf with rg integration and searching a large directory. Occasionally, the query being processed by rg is not the same as the query displayed by fzf and only after further modifying the query or waiting until rg finishes will the input reload to the correct state. This commit introduces a 'started' condition that the terminate method will wait for before trying to kill the process. The 'started' condition is signalled only when the reader reaches a state where it can be safely terminated.
Is there any way I can easily reproduce the problem without having to rely on ripgrep and a large directory? Maybe using a contrived command with |
fzf --disabled --bind 'change:reload:echo Current query: {q} && sleep 1d' When running this command, sometimes when you stop typing a query you may see that the item list does not update for the latest version of the query. You either have to wait 1 day or modify the query for the item list to update. fzf-race-2-20fps.mp4Notice at the end of the video the query is "i like to use fzf" but the item in the list of results says "i like to use fz". |
Thanks, I can reproduce the problem. I believe your patch will fix the problem, but the fundamental reason we have this race in the first place is that we "restart" the process asynchronously in a go routine. Line 302 in 82ebcd9
So I think a more direct way to fix it is to not do it asynchronously, i.e. remove |
Please see dcb4c3d and let me know if it doesn't fix the problem, or you find any flaw in the patch. Thanks. |
Thank you! dcb4c3d does fix the problem I was encountering. I did notice 3 minor issues when reading through
In action: fzf --disabled --bind "start:reload:echo start command; sleep 1d" --bind "change:reload:echo reloaded input with query {q}" read-source-race-20fps.mp4
Here is a contrived example: (while true; do echo stdin data; sleep 10; done) | fzf --disabled --bind "change:reload:echo reloaded with: {q}" fzf-stdin-reload-20fps.mp4This is because the stdin file is in blocking mode. Calling |
Thank you very much for the detailed analysis. I'll address the issues and let you know of the progress. |
I believe 19495eb addresses the first two issues you mentioned. It restored the previous code structure, but added a barrier using a channel to ensure that the process has started. I'm not going to think too much about the third issue for now, as I'm afraid trying to fix it might cause other side effects (e.g. affecting the ingestion performance) and we can work around it using a fzf --disabled \
--bind 'change:reload:echo reloaded with: {q}' \
--bind 'start:reload:while true; do echo stdin data; sleep 10; done' Thanks for your feedback! |
Hmm, the last commit has a bug that can freeze fzf when a process failed to start. Let me see.. fzf --bind change:reload:ls --with-shell xxx EDIT: Fixed in acdf265 |
Thank you! |
This MR contains the following updates: | Package | Update | Change | |---|---|---| | [junegunn/fzf](https://github.com/junegunn/fzf) | minor | `v0.55.0` -> `v0.56.3` | MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot). **Proposed changes to behavior should be submitted there as MRs.** --- ### Release Notes <details> <summary>junegunn/fzf (junegunn/fzf)</summary> ### [`v0.56.3`](https://github.com/junegunn/fzf/releases/tag/v0.56.3): 0.56.3 [Compare Source](junegunn/fzf@v0.56.2...v0.56.3) - Bug fixes in zsh scripts - fix(zsh): handle backtick trigger edge case ([#​4090](junegunn/fzf#4090)) - revert(zsh): remove 'fc -RI' call in the history widget ([#​4093](junegunn/fzf#4093)) - Thanks to [@​LangLangBart](https://github.com/LangLangBart) for the contributions ### [`v0.56.2`](https://github.com/junegunn/fzf/releases/tag/v0.56.2): 0.56.2 [Compare Source](junegunn/fzf@v0.56.1...v0.56.2) - Bug fixes - Fixed abnormal scrolling behavior when `--wrap` is set ([#​4083](junegunn/fzf#4083)) - \[zsh] Fixed warning message when `ksh_arrays` is set ([#​4084](junegunn/fzf#4084)) ### [`v0.56.1`](https://github.com/junegunn/fzf/releases/tag/v0.56.1): 0.56.1 [Compare Source](junegunn/fzf@v0.56.0...v0.56.1) - Bug fixes and improvements - Fixed a race condition which would cause fzf to present stale results after `reload` ([#​4070](junegunn/fzf#4070)) - `page-up` and `page-down` actions now work correctly with multi-line items ([#​4069](junegunn/fzf#4069)) - `{n}` is allowed in `SCROLL` expression in `--preview-window` ([#​4079](junegunn/fzf#4079)) - \[zsh] Fixed regression in history loading with shared option ([#​4071](junegunn/fzf#4071)) - \[zsh] Better command extraction in zsh completion ([#​4082](junegunn/fzf#4082)) - Thanks to [@​LangLangBart](https://github.com/LangLangBart), [@​jaydee-coder](https://github.com/jaydee-coder), [@​alex-huff](https://github.com/alex-huff), and [@​vejkse](https://github.com/vejkse) for the contributions ### [`v0.56.0`](https://github.com/junegunn/fzf/releases/tag/v0.56.0): 0.56.0 [Compare Source](junegunn/fzf@v0.55.0...v0.56.0) - Added `--gap[=N]` option to display empty lines between items. - This can be useful to visually separate adjacent multi-line items. ```sh ``` ### All bash functions, highlighted declare -f | perl -0777 -pe 's/^}\n/}\0/gm' | bat --plain --language bash --color always | fzf --read0 --ansi --reverse --multi --highlight-line --gap ``` <img width="855" alt="image" src="https://github.com/user-attachments/assets/b3d2eaf2-bf44-4e3a-8d7b-9878629dd9be"> - Or just to make the list easier to read. For single-line items, you probably want to set `--color gutter:-1` as well to hide the gutter. ```sh fzf --info inline-right --gap --color gutter:-1 ``` <img width="855" alt="image" src="https://github.com/user-attachments/assets/113757a1-ccfd-42a6-b946-83533f408e69"> - Added `noinfo` option to `--preview-window` to hide the scroll indicator in the preview window - Bug fixes - Thanks to [@​LangLangBart](https://github.com/LangLangBart), [@​akinomyoga](https://github.com/akinomyoga), and [@​charlievieth](https://github.com/charlievieth) for fixing the bugs </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this MR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box --- This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40NDAuNyIsInVwZGF0ZWRJblZlciI6IjM3LjQ0MC43IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiXX0=-->
reader: Fixed race condition where reader would be terminated before it was properly initialized.
Currently, when reloading input very quickly (happens when updating the prompt quickly with 'reload' bound to 'change') it is possible for the reader's terminate method to be called before readFromCommand properly spawns the new reader process. This means the process is never killed and input is not reloaded until the process completes naturally or another 'EvtSearchNew' is triggered.
An example where this becomes a problem is when using fzf with rg integration and searching a large directory. Occasionally, the query being processed by rg is not the same as the query displayed by fzf and only after further modifying the query or waiting until rg finishes will the input reload to the correct state. This commit introduces a 'started' condition that the terminate method will wait for before trying to kill the process. The 'started' condition is signalled only when the reader reaches a state where it can be safely terminated.