Why Thread.abort_on_exception = yes doesn't show errors?

  • Thread starter Iñaki Baz Castillo
  • Start date
I

Iñaki Baz Castillo

Hi, when Thread.abort_on_exception =3D yes I don't see any error log in the=
=20
screen. Note those cases:


case 1) It's seems correct:
=2D--------------------
t =3D Thread.new {
sleep 1
qwe
}
t.abort_on_exception =3D true

puts "hello !!!"
sleep 2
puts "END"
=2D--------------------
=3D>
hello !!!
test.rb:3: undefined local variable or method `qwe' for main:Object=20
(NameError)
from test.rb:1:in `initialize'
from test.rb:1:in `new'
from test.rb:1



case 2) Why the error is not shown???
=2D--------------------
t =3D Thread.new {
sleep 1
qwe
}
t.abort_on_exception =3D false

puts "hello !!!"
sleep 2
puts "END"
=2D--------------------
=3D> =20
hello !!!
END



case 3) But if I do a t.join then the error is shown and the program=20
exists !!!:
=2D--------------------
t =3D Thread.new {
sleep 1
qwe
}
t.abort_on_exception =3D false

puts "hello !!!"
t.join
puts "END"
=2D--------------------
=3D> =20
hello !!!
test.rb:3: undefined local variable or method `qwe' for main:Object=20
(NameError)
from test.rb:8:in `join'
from test.rb:8



Conclusion:

=2D If a thread is joined then if that threads has a non handled exception =
the=20
program will exit (except if the main program handles that exception).

=2D If a thread is "abort_on_exception =3D true" then the program will fail=
in the=20
moment the thread fails (it makes sense).

=2D If a thead is "abort_on_exception =3D false" then nothing will occur if=
the=20
threads fails, and no error output will occur. WHY ???


Any comment is appreciated.

=2D-=20
I=C3=B1aki Baz Castillo
 
J

Joel VanderWerf

Iñaki Baz Castillo said:
- If a thread is joined then if that threads has a non handled exception the
program will exit (except if the main program handles that exception).

- If a thread is "abort_on_exception = true" then the program will fail in the
moment the thread fails (it makes sense).

- If a thead is "abort_on_exception = false" then nothing will occur if the
threads fails, and no error output will occur. WHY ???

That's all intended, IIUC. Point #1 above implies point #3: suppose
threads _always_ reported exceptions. Then if you wrote a program to
take advantage of #1 by harvesting finished threads and handling their
exceptions in the main thread (or more generally the joining thread) you
would have spurious exception dumping. You have more control this way,
but you have to remember to either set abort_on_exception or to wrap
your thread in a handler or to join the thread later. These are three
styles, each of which has its place.
 
I

Iñaki Baz Castillo

El Domingo, 20 de Julio de 2008, Joel VanderWerf escribi=C3=B3:
You have more control this way,
but you have to remember to either set abort_on_exception or to wrap
your thread in a handler or to join the thread later. These are three
styles, each of which has its place.

Well, thanks for the explanation but I have a doubt.

I run a thread "t2" inside thread "t1" but I don't want "t1" to wait to "t2=
"=20
to finish, this is: I don't need "t1" joins "t2".

I also don't want the main program ends because "t2" produces an exception=
=20
that nobody handles, but I want to see the error. Is not a way to get this=
=20
behaviour?

The only solution I see is t1 joins t2, is it?

Thanks a lot.

=2D-=20
I=C3=B1aki Baz Castillo
 
I

Iñaki Baz Castillo

El Domingo, 20 de Julio de 2008, I=C3=B1aki Baz Castillo escribi=C3=B3:
El Domingo, 20 de Julio de 2008, Joel VanderWerf escribi=C3=B3:

Well, thanks for the explanation but I have a doubt.

I run a thread "t2" inside thread "t1" but I don't want "t1" to wait to
"t2" to finish, this is: I don't need "t1" joins "t2".

I also don't want the main program ends because "t2" produces an exception
that nobody handles, but I want to see the error. Is not a way to get this
behaviour?

The only solution I see is t1 joins t2, is it?

Humm, but this is not valid for me, I explain why:

I'm using GServer, so it creates a Thread for each incoming TCP connection =
and=20
runs "serve" method for each one.

In "serve" method I parse the TCP incoming data and process it, but I need=
=20
this connection to remain open and accepting new data even if the received=
=20
data hasn't be processed yet (it's a SIP server). So, in resume I do:


=2D--------------------------------
class GServer

# New Thread for a new IO.
def serve(io)

loop do

data =3D read_IO_incoming_data()
Thread.new {
Logic::process(data)
}

end # loop

end # def serve

end # class GServer
=2D------------------------------

As you see, I need the TCP connection remains open and available ALL the ti=
me,=20
I can wait to process the last received data, so I run a Thread and repeat=
=20
**inmediately** the loop.

Also I need that if an exception occurs in Logic::process(data) it being sh=
own=20
but don't stop the programm (abort_on_exception =3D false). But in this way=
I=20
can't see the error output if it occurs.

How could I get showing the error into the Thread without doing a "join"? (=
I=20
can't do a join).

Thanks a lot for any suggestion.


=2D-=20
I=C3=B1aki Baz Castillo
 
I

Iñaki Baz Castillo

El Domingo, 20 de Julio de 2008, I=C3=B1aki Baz Castillo escribi=C3=B3:
As you see, I need the TCP connection remains open and available ALL the
time, I can wait to process the last received data, so I run a Thread and
repeat **inmediately** the loop.

Also I need that if an exception occurs in Logic::process(data) it being
shown but don't stop the programm (abort_on_exception =3D false). But in = this
way I can't see the error output if it occurs.

How could I get showing the error into the Thread without doing a "join"?
(I can't do a join).

Thanks a lot for any suggestion.

Opss, I think I have the solution :)

=2D--------------------------------
class GServer

# New Thread for a new IO.
def serve(io)

loop do

data =3D read_IO_incoming_data()
Thread.new {
begin
Logic::process(data)
rescue =3D> e
puts "#{e.class}: #{$!}"
end
}

end # loop

end # def serve

end # class GServer
=2D------------------------------


Is it OK? :)


=2D-=20
I=C3=B1aki Baz Castillo
 
J

Joel VanderWerf

Iñaki Baz Castillo said:
Thread.new {
begin
Logic::process(data)
rescue => e
puts "#{e.class}: #{$!}"
end
}

Yes, that's a standard practice. That's what I meant by "wrap your
thread in a handler" (sorry that was a bit unclear).
 
I

Iñaki Baz Castillo

El Lunes, 21 de Julio de 2008, Joel VanderWerf escribi=C3=B3:
Yes, that's a standard practice. That's what I meant by "wrap your
thread in a handler" (sorry that was a bit unclear).

Yeah, now after reading again you mail I understood it better :)

Thanks a lot for your help.

=2D-=20
I=C3=B1aki Baz Castillo
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top