Saving simultaneous errors that occur inside threads

With the following script

threads = [
  Thread.new { Thread.current.abort_on_exception = true; raise 'err' },
  Thread.new { Thread.current.abort_on_exception = true; raise 'err' },
]

begin
  threads.each(&:join)
rescue RuntimeError
  puts "Got Error"
end

In half the cases, I get the expected "Got Error" with the output 0, and the second half I get test.rb:3:in block in <main>': err (RuntimeError).

Is it possible to cope with this salvation? If not for some alternative solutions for two threads that simultaneously caused an error?

I thought I wasn’t using it abort_on_exception = true, but the problem is that if the first thread has, say, sleep(10)before raise, the second thread, whose errors immediately, will not get up to 10 seconds (due to the order of the array threads).

Ruby MRI version: ruby ​​2.4.0p0 (version 2016-12-24 57164) [x86_64-darwin15]

Any ideas would be highly appreciated. Thank!

Update

jruby-9.1.6.0, , . , , . Got Error - . , JRuby .

+4
2

.


-, :

Thread.new { Thread.current.abort_on_exception = true; raise 'Oh, no!' }

puts 'Ready or not, here I come'

.


-, , , , #join:

gollum = Thread.new { raise 'My precious!!!' }

begin
  gollum.join
rescue => e
  # Prints 'My precious!!!'
  puts e.message
end

, . , - . , , , . threads.each(&:join) , - :

frodo = Thread.new { raise 'Oh, no, Frodo!' }
sam   = Thread.new { raise 'Oh, no, Sam!' }

begin
  [frodo, sam].each(&:join)
rescue => e
  puts e.message
end

puts 'This is the end, my only friend, the end.'

, , !
, , .


:

frodo = Thread.new { Thread.current.abort_on_exception = true; raise 'Oh, no, Frodo!' }
sam   = Thread.new { Thread.current.abort_on_exception = true; raise 'Oh, no, Sam!' }

begin
  [frodo, sam].each(&:join)
rescue => e
  puts e.message
end

puts 'This is the end, my only friend, the end.'

. , ( ), , , , . (, , ) , .


:

ex.rb: 1: in `block in ': , , ! (RuntimeError)

, .

, , !
, , .

, , . , , . , .

, , ! ex.rb: 2: : , , ! (RuntimeError)

. , . , .

, , !
, , end.ex.rb: 1: in `block in ': , , ! (RuntimeError)

( ) . , . . , , , .


, , , . , , , :

def execute_safely_concurrently(number_of_threads, &work)
  return if number_of_threads.zero?

  begin
    Thread.new(&work).join
  rescue => e
    puts e
  end

  execute_safely_concurrently(number_of_threads.pred, &work)
end

execute_safely_concurrently(2) do
  Thread.current.abort_on_exception = true
  raise 'Handle me, bitte!'
end
+1

@ndn . , . , .

@threads = []
def execute_safely_concurrently(&work)
  begin
    @threads << Thread.new(&work)
  rescue RuntimeError => e
    puts "Child Thread Rescue: #{e}"
  end
end

execute_safely_concurrently do
  Thread.current.abort_on_exception = true
  sleep(3)
  raise 'Handle me, bitte 1!'
end

execute_safely_concurrently do
  Thread.current.abort_on_exception = true
  raise 'Handle me, bitte 2!'
end

begin
  @threads.each(&:join)
rescue RuntimeError => e
  puts "Main Thread Rescue: #{e}"
end
0

Source: https://habr.com/ru/post/1667230/


All Articles