-
Notifications
You must be signed in to change notification settings - Fork 136
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
Conversation
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.
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
oil.nvim/lua/oil/adapters/ssh/connection.lua
Lines 285 to 312 in c4cc824
---@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.
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? |
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.
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.
I didn't undestand how |
I shuffled around some of the logic. LMK if this makes sense (and if it still works for you) |
Looks good to me and it's working as expected c: |
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 (?).