Background:
currently if you have a thread that “dies” without being cleaned up
Thread.new {
raise ‘you never see this message’
}
sleep
The error messages are basically swallowed, which I always find
surprising–they aren’t for the main thread but they are for internal
threads.
RCR is to default to abort_on_exception to true.
Thoughts?
=r
Hi,
In message “Re: [RCR] Thread.abort_on_exception default to true”
on Tue, 21 Jul 2009 06:19:55 +0900, Roger P.
[email protected] writes:
|Background:
|currently if you have a thread that “dies” without being cleaned up
What do you mean by “clean up” here? If you care about the thread
status, you can call join, that reports the exception inside of the
thread.
matz.
What do you mean by “clean up” here? If you care about the thread
status, you can call join, that reports the exception inside of the
thread.
I agree that using #join here would result in cleanup that would allow
the exception to no longer be swallowed–however I will explain my side
of it. Typically one uses join to mean only “wait for
termination”–using it as cleanup has always felt surprising to me, and
whenever I start a new multi-thread application, I am almost always
surprised by the fact that some error messages are swallowed.
here’s a (somewhat contrived) ex:
"deep within a some server: "
Thread.new { send an email }
continue running, handle next request, etc.
In this instance, I don’t want to join on the thread because I am not
concerned about when it finishes–it doesn’t matter to me, and I don’t
want to wait for it as it would slow up processing my next request.
Therefore the exception is forgotten.
I only mention it because this just happened to me (again–this time
while debugging someone else’s code, but), it surprised me once more,
hence my noting it here–perhaps as a compromise threads could output
the uncaught backtrace to stderr unless #join has already been called on
the thread? I realize there are problems with that, too, just thinking
for options.
Thoughts?
Thanks.
=r
Yukihiro M. wrote:
thread.
If you don’t know when a thread will finish, it’s hard to know when to
call join. I’m not arguing for the RCR, though. The default makes sense
to me–one poorly-rescued thread won’t take down the process.
Still, I don’t see an easy way for a master thread to wait for worker
threads to finish and report their results as soon as they are
available. The alternatives:
-
thread.each {|t| t.join} # blocks on first running thread
-
polling
-
queues
Maybe if there were a ThreadGroup#wait or something…
Hi,
In message “Re: Thread.abort_on_exception default to true”
on Tue, 21 Jul 2009 06:45:03 +0900, Roger P.
[email protected] writes:
|here’s a (somewhat contrived) ex:
|
|"deep within a some server: "
|
|Thread.new { send an email }
|
|# continue running, handle next request, etc.
|
|In this instance, I don’t want to join on the thread because I am not
|concerned about when it finishes–it doesn’t matter to me, and I don’t
|want to wait for it as it would slow up processing my next request.
|Therefore the exception is forgotten.
I think you’d better handle the exception in the thread block.
abort_on_exception means asynchronous exceptions will be delivered to
the main thread. That means any exception may happen on any point in
the main thread. From my point of view, asynchronous exception is
like a nightmare, especially for production code. Most code is not
exception safe at that level. That is the reason abort_on_exception
to be false by default. That is only for debugging purpose.
matz.
Justin C. wrote:
There is ThreadsWait#all_waits which can execute a block as each thread
ends, and there is ThreadsWait#next_wait which returns the next thread
that terminates.
http://ruby-doc.org/stdlib/libdoc/thwait/rdoc/classes/ThreadsWait.html
Yep, that’s what I was looking for. Thanks!
Roger P. wrote:
In this instance, I don’t want to join on the thread because I am not
concerned about when it finishes–it doesn’t matter to me, and I don’t
want to wait for it as it would slow up processing my next request.
Therefore the exception is forgotten.
You don’t care if or when it finishes, but you also don’t mind if it
crashes your main program by raising an asynchronous exception?
abort_on_exception means asynchronous exceptions will be delivered to
the main thread. That means any exception may happen on any point in
the main thread. From my point of view, asynchronous exception is
like a nightmare, especially for production code. Most code is not
exception safe at that level. That is the reason abort_on_exception
to be false by default. That is only for debugging purpose.
Hmm. True (I’ve even thought before that Thread#raise should be
deprecated–too dangerous, can interrupt code in a finally block, etc).
That being said, could it perhaps at least output something to stderr by
default to satisfy both cases?
Thanks.
-=r
Joel VanderWerf wrote:
What do you mean by “clean up” here? If you care about the thread
-
thread.each {|t| t.join} # blocks on first running thread
-
polling
-
queues
Maybe if there were a ThreadGroup#wait or something…
There is ThreadsWait#all_waits which can execute a block as each thread
ends, and there is ThreadsWait#next_wait which returns the next thread
that terminates.
http://ruby-doc.org/stdlib/libdoc/thwait/rdoc/classes/ThreadsWait.html
-Justin
Hi,
In message “Re: Thread.abort_on_exception default to true”
on Wed, 22 Jul 2009 00:00:03 +0900, Roger P.
[email protected] writes:
|That being said, could it perhaps at least output something to stderr by
|default to satisfy both cases?
Something to stderr is only useful in debugging, but no good for
production code. When debugging, put -d to the command line options.
It automatically enable abort_on_exception.
matz.
Something to stderr is only useful in debugging, but no good for
production code. When debugging, put -d to the command line options.
It automatically enable abort_on_exception.
Sounds good. I suppose the -d option is underused by most people
including myself.
=r