KnapsackPro / knapsack_pro-ruby

Knapsack Pro gem splits tests across parallel CI nodes and makes sure that tests run in optimal time
https://knapsackpro.com
MIT License
131 stars 27 forks source link

Avoid unnecessary process in queue mode #260

Closed 3v0k4 closed 3 months ago

3v0k4 commented 3 months ago

Story

Ticket

#system executes the passed command into a subshell. It pretty much executes fork, exec, and wait.

#exec replaces the current process avoiding a fork/wait.

Also, using exec delegates the exit/error handling to the replacing process making the code introduced in https://github.com/KnapsackPro/knapsack_pro-ruby/commit/7862c5e6 unneeded:

      exitstatus = $?.exitstatus
      if exitstatus.nil?
        puts 'Something went wrong. Most likely, the process has been killed. Knapsack Pro has been terminated.'
        Kernel.exit(1)
      else
        Kernel.exit(exitstatus)
      end

Also the following form seems to work:

Kernel.exec({ "RAILS_ENV" => "test", "RACK_ENV" => "test" }, "#{$PROGRAM_NAME} 'knapsack_pro:queue:rspec_go[#{args[:rspec_args]}]'")

See the #spawn docs for more on that.

Reference:

Checklist reminder

Manual Tests

namespace :knapsack_pro do
  namespace :queue do
    task :rspec, [:rspec_args] do |_, args|
      Kernel.exec("RAILS_ENV=test RACK_ENV=test RAILS_X=something #{$PROGRAM_NAME} 'knapsack_pro:queue:rspec_go[#{args[:rspec_args]}]'")
      raise "err"
    end

    task :rspec_go, [:rspec_args] do |_, args|
      puts ENV.filter { |k, v| k.include?("RAILS_") }
      exit 10
    end
  end
end
$ bin/knapsack_pro_queue_rspec 1 2 20240601-01
{"RAILS_X"=>"something", "RAILS_ENV"=>"test"}

$ echo $?
10
namespace :knapsack_pro do
  namespace :queue do
    task :rspec, [:rspec_args] do |_, args|
      Kernel.exec("RAILS_ENV=test RACK_ENV=test RAILS_X=something #{$PROGRAM_NAME} 'knapsack_pro:queue:rspec_go[#{args[:rspec_args]}]'")
      raise "err"
    end

    task :rspec_go, [:rspec_args] do |_, args|
      puts ENV.filter { |k, v| k.include?("RAILS_") }
      raise StandardError
    end
  end
end
$ bin/knapsack_pro_queue_rspec 1 2 20240601-01
{"RAILS_X"=>"something", "RAILS_ENV"=>"test"}
rake aborted!
StandardError: StandardError (StandardError)
/Users/3v0k4/code/knapsack/knapsack_pro-ruby/lib/tasks/queue/rspec.rake:14:in `block (3 levels) in <top (required)>'
/Users/3v0k4/.rvm/gems/ruby-3.2.2/gems/rake-13.2.1/exe/rake:27:in `<top (required)>'
/Users/3v0k4/.rvm/gems/ruby-3.2.2/bin/ruby_executable_hooks:22:in `eval'
/Users/3v0k4/.rvm/gems/ruby-3.2.2/bin/ruby_executable_hooks:22:in `<main>'
Tasks: TOP => knapsack_pro:queue:rspec_go
(See full trace by running task with --trace)