PERF: Switch `plugins:update_all` to git pull concurrently (#24513)

Why this change?

Similar to d0117ff6e3, `plugins:update_all` spends most of its time waiting
on the network. On my local machine, this takes up to 2 mins when I have
all the official plugins installed. On a 32 cores machine, the total
time is cut down to 4 seconds.

What does this change do?

1. Move the logic in the `plugin:update` Rake task into a method.
2. Updates the `plugin:update` and `plugin:update_all` to rely on the
   new method.
3. Wraps the method call to update a plugin in `plugin:update_all` in a
   `Concurrent::Promise`

This change also adds the `--quiet` option to the `git pull` option
since the `git pull` output is just noise for 99% of the time.
This commit is contained in:
Alan Guo Xiang Tan 2023-11-23 07:08:32 +08:00 committed by GitHub
parent e395e5e002
commit 1e290eed7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 23 additions and 17 deletions

View File

@ -65,22 +65,8 @@ task "plugin:install", :repo do |t, args|
end
end
desc "update all plugins"
task "plugin:update_all" do |t|
# Loop through each directory
plugins = Dir.glob(File.expand_path("plugins/*")).select { |f| File.directory? f }
# run plugin:update
plugins.each do |plugin|
next unless File.directory?(plugin + "/.git")
Rake::Task["plugin:update"].invoke(plugin)
Rake::Task["plugin:update"].reenable
end
Rake::Task["plugin:versions"].invoke
end
desc "update a plugin"
task "plugin:update", :plugin do |t, args|
plugin = ENV["PLUGIN"] || ENV["plugin"] || args[:plugin]
def update_plugin(plugin)
plugin = ENV["PLUGIN"] || ENV["plugin"] || plugin
plugin_path = plugin
plugin = File.basename(plugin)
@ -112,10 +98,30 @@ task "plugin:update", :plugin do |t, args|
`git -C '#{plugin_path}' branch -u origin/main main`
end
update_status = system("git -C '#{plugin_path}' pull --no-rebase")
update_status = system("git -C '#{plugin_path}' pull --quiet --no-rebase")
abort("Unable to pull latest version of plugin #{plugin_path}") unless update_status
end
desc "update all plugins"
task "plugin:update_all" do |t|
# Loop through each directory
plugins =
Dir
.glob(File.expand_path("plugins/*"))
.select { |f| File.directory?(f) && File.directory?("#{f}/.git") }
# run plugin:update
promises = plugins.map { |plugin| Concurrent::Promise.execute { update_plugin(plugin) } }
Concurrent::Promise.zip(*promises).value!
Rake::Task["plugin:versions"].invoke
end
desc "update a plugin"
task "plugin:update", :plugin do |t, args|
update_plugin(args[:plugin])
end
desc "pull compatible plugin versions for all plugins"
task "plugin:pull_compatible_all" do |t|
STDERR.puts <<~TEXT if GlobalSetting.load_plugins?