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

[main-] fix rare duplication of replay cmds #2392

Merged
merged 1 commit into from
May 20, 2024

Conversation

midichef
Copy link
Contributor

When replaying command files, in rare circumstances, some commands can be run twice.

The cause is that reload() is called twice for the command file. Once inside eval_vd(), and again after eval_vd() finishes:

vs.reload()
vd.sync(vs.reload())

Both reload() calls can run at the same time in two different threads, because TableSheet.reload() has the @asyncthread decorator. Both threads add to self.rows via self.addRow(r) in TableSheet.loader(), so command rows can get added twice.

The specific events that must happen to trigger the bug are:

  1. the first reload() call must run TableSheet.loader(), past the line of self.rows = []
    self.rows = []
  2. before that reload() finishes adding rows, the second reload() call must run TableSheet.loader(), past the line of self.rows = []
  3. before the second reload() call finishes adding rows, the first call continues adding rows

I made a pathological loader that triggers these conditions every time, by loading only two command rows per second : 5c97a84. To test with that loader, do touch row_duplication.slow; vd -p dupes.slow, and see that the dupes_vd sheet contains more than 5 commands. The loader only generates 5 commands, but in my tests, the demo code duplicates all of them, for a total of 10 commands.

The affected versions of Visidata could be multiple versions since Sep 2019, as of 330117f. But on my system, I have not yet found a way to trigger it for replay files that are short (under 100 lines). For much longer files, it does happen every time. For example, it happens if I add ~5000 lines of comments to a short .vdj file. But for short files with no comments (~10 lines), I couldn't trigger it at all by adding CPU/IO/disk stress via the Ubuntu stress binary, in ~500 tries.

Copy link
Owner

@saulpw saulpw left a comment

Choose a reason for hiding this comment

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

Thank you for this fix, and the corresponding analysis. This makes sense to me.

@anjakefala anjakefala merged commit 54f8147 into saulpw:develop May 20, 2024
13 checks passed
@midichef midichef deleted the replay_row_duplication branch May 25, 2024 09:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants