Skip to content

HerokuRun#run_shell! is not threadsafe #157

Closed
@dzuelke

Description

@dzuelke
Contributor

This:

    private def run_shell!
      @output = `#{@command}`
      @status = $?
    end

... will blow up with run_multi, because all sorts of things can happen in between the backticks and the reading of $?.

Activity

schneems

schneems commented on Jan 13, 2021

@schneems
Contributor

As explained in #157, backticks followed by $? access aren't threadsafe

That's not true. $? is threadsafe:

threads = []
100.times do
  threads << Thread.new do
    value = rand(0..10)
    `exit #{value}`
    {expected: value, actual: $?.exitstatus }
  end
end

threads.join
output = threads.map(&:value)

output.each do |hash|
  raise "oh no #{hash}" if hash[:expected] != hash[:actual]
end

# => No error

or

$ irb
irb(main):001:0> $?
=> nil
irb(main):002:0>  Thread.new { `exit 1` }
=> #<Thread:0x00007fb7fe0c92f8 (irb):2 run>
irb(main):003:0> $?
=> nil
irb(main):004:0> $?
=> nil
irb(main):005:0` `exit 2`
=> ""
irb(main):006:0> $?
=> #<Process::Status: pid 71731 exit 2>
dzuelke

dzuelke commented on Jan 14, 2021

@dzuelke
ContributorAuthor

That's only within a thread, right? Outside the thread you're not guaranteed that.

So what about this:

Hatchet::Runner.new("default_ruby", run_multi: true)
  app.run_multi("ls") do |out, status|
    expect(status.success?).to be_truthy
    expect(out).to include("Gemfile")
  end
  app.run_multi("ruby -v") do |out, status|
    expect(status.success?).to be_truthy
    expect(out).to include("ruby")
  end
  puts $?
end

Which of the two runs' $? will puts print?

schneems

schneems commented on Jan 14, 2021

@schneems
Contributor

4 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @dzuelke@schneems

        Issue actions

          HerokuRun#run_shell! is not threadsafe · Issue #157 · heroku/hatchet