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

perf(trash_windows): use a single powershell instance for operations #271

Merged
merged 6 commits into from
Jan 16, 2024
Merged

perf(trash_windows): use a single powershell instance for operations #271

merged 6 commits into from
Jan 16, 2024

Conversation

TheLeoP
Copy link
Contributor

@TheLeoP TheLeoP commented Jan 6, 2024

As mentioned in #243, trash support on windows is slow for some operations because it spawns a powershell process for every operation (sending 10 files to trash would spawn 10 powershell instances).

This PR starts two powershell intances (one for listing and one for deleting) and communicates with them over stdio (sending 10 files to trash now spawns only 1 powershell instance).

This improves the performance of trash related operations in windows after the first operation (because it's neccesary to start the powershell instance the first time). Maybe it could be preffered to start the powershell instances on startup instead (?).

Copy link
Owner

@stevearc stevearc left a comment

Choose a reason for hiding this comment

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

With all the global (module-local) variables, this starts to get difficult to reason about. I'm pretty sure there are race conditions here if one of the methods gets called in quick succession. What I'd like to see is a refactoring to push this new added complexity into a self-contained file that exposes a clean API for this trash adapter to delete and restore files. You can take a look at what I'm doing for SSH connections, because it's very similar. In particular, look at this section

---@param command string
---@param callback fun(err: nil|string, lines: nil|string[])
function SSHConnection:run(command, callback)
if self.connection_error then
callback(self.connection_error)
else
table.insert(self.commands, { cmd = command, cb = callback })
self:_consume()
end
end
function SSHConnection:_consume()
if self.connected and not vim.tbl_isempty(self.commands) then
local cmd = self.commands[1]
if not cmd.running then
cmd.running = true
vim.api.nvim_chan_send(
self.jid,
-- HACK: Sleep briefly to help reduce stderr/stdout interleaving.
-- I want to find a way to flush the stderr before the echo DONE, but haven't yet.
-- This was causing issues when ls directory that doesn't exist (b/c ls prints error)
'echo "===BEGIN==="; '
.. cmd.cmd
.. '; CODE=$?; sleep .01; echo "===DONE($CODE)==="\r'
)
end
end
end

This ensures that the commands get executed sequentially because there's no way for a single process to do two at once.

@TheLeoP
Copy link
Contributor Author

TheLeoP commented Jan 9, 2024

Is this approach ok? I'm not sure about how the initial command are handled (I tried to use coroutines, but got an error because they can't be used across c call boundaries). Also, the API isn't trash specific, would an trash specific API be preffered?

Copy link
Owner

@stevearc stevearc left a comment

Choose a reason for hiding this comment

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

This already looks better! I think for this particular case I'd like to see even more of the powershell trash logic pulled out into a different file. Right now the logic for "check if powershell job is running, create one if not" lives in the windows trash adapter file, and it just makes it a little cluttered. It's already a pretty long file with a decent amount of complexity surrounding trash semantics; it would be nice to put all the complexity of managing long-lived jobs into a different file.

@github-actions github-actions bot requested a review from stevearc January 15, 2024 01:19
@TheLeoP
Copy link
Contributor Author

TheLeoP commented Jan 15, 2024

I didn't undestand how _consume was suppossed to work inside the on_stdout callback and your comment made it click for me. This allowed me to simplify the initialization code a lot. Is it better? Or would it still be preffered to extract it into a different file?

@stevearc
Copy link
Owner

I shuffled around some of the logic. LMK if this makes sense (and if it still works for you)

@TheLeoP
Copy link
Contributor Author

TheLeoP commented Jan 16, 2024

Looks good to me and it's working as expected c:

@stevearc stevearc merged commit e71b6ca into stevearc:master Jan 16, 2024
8 checks passed
@TheLeoP TheLeoP deleted the windows_trash_perf branch January 16, 2024 01:33
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.

2 participants