Handling exceptions in Threads

G

Guillermo.Acilu

Hello guys,

I have made an multithreaded algorithm that triggers around a hundred=20
concurrent threads. I have in fact, two versions of the same algorithm,=20
one with threads and another with recursive calls.

Each thread execute a query on an Oracle database and according to the=20
data, it either calls a new thread and ends, or it stores the result in a=20
global array. The recursive version follow the same process, but instead=20
or running in parallel, it calls the method over and over sequentially.

The recursive version runs perfectly and it ends without problem. The=20
multithreaded version fails with an exception that I am not able to=20
identify.

If I leave the Thread.abort=5Fon=5Fexception =3D false, the algorithm ends =
after=20
triggering about 10 threads. If I set it to Thread.abort=5Fon=5Fexception =
=3D=20
true, the algorithm end abnormally, but without printing any error=20
message.

I have added the following code at the end of the method called by the=20
thread:

rescue Exception =3D> error
puts "#{error.class}: #{error.message}"

But I cannot get any error message in the console. I am sure that the=20
problem is something related with the database, but I do not know how to=20
solve the problem if I do not see the error message.

Any ideas?

---
Guillermo Acilu
Senior Engineer, Koiaka GmbH

Koiaka GmbH
Riesserkopfstr. 17=20
82467 Garmisch-Partenkirchen
Tel: +49 (0)8821 9679555=20
Fax: +49 (0)8821 730 9185=20
Mailto:[email protected]
http://www.koiaka.com

Amtsgericht M=FCnchen: HR B 161 041=20
Gesch=E4ftsf=FChrer: Guillermo Acilu=20
Sitz: Garmisch-Partenkirchen

Diese Email kann vertrauliche und/oder rechtlich gesch=FCtzte Informationen=
=20
enthalten. Wenn Sie nicht der richtige Adressat sind oder diese Email=20
irrt=FCmlich erhalten haben, d=FCrfen Sie diese weder benutzen, kopieren,=20
weiterleiten oder irgend eine Ma=DFnahme einleiten, die im Zusammenhang mit=
=20
dem Inhalt dieser Email steht. Informieren Sie bitte sofort den Absender=20
und vernichten Sie die irrt=FCmlich erhaltene Email vollst=E4ndig.
Vielen Dank!

This e-mail message may contain confidential and/or privileged=20
information. If you are not an addressee or otherwise authorized to=20
receive this message, you should not use, copy, disclose or take any=20
action based on this e-mail or any information contained in the message.=20
If you have received this material in error, please advise the sender=20
immediately by reply e-mail and delete this message completely.
Thank you!
 
J

Joel VanderWerf

But I cannot get any error message in the console. I am sure that the
problem is something related with the database, but I do not know how to
solve the problem if I do not see the error message.

Why are you sure it is the database? If your other version (the
recursive one) works, then that suggests the db calls are ok, doesn't it?
 
A

ara.t.howard

If I leave the Thread.abort_on_exception = false, the algorithm ends
after
triggering about 10 threads. If I set it to
Thread.abort_on_exception =
true, the algorithm end abnormally, but without printing any error
message.

I have added the following code at the end of the method called by the
thread:

rescue Exception => error
puts "#{error.class}: #{error.message}"

But I cannot get any error message in the console. I am sure that the
problem is something related with the database, but I do not know
how to
solve the problem if I do not see the error message.

Any ideas?


1) STDERR.puts message

stdout bufferes and can get lost


2) it's *highly* unlikely the db handle is thread safe and, if it is,
it'll be native thread safe not green thread safe. aka - you will not
get anything from using MT to execute your queries.


so, just use producer/consumer to both simplify and speed up your
application. for example


q = Queue.new

queries = list_of_queries

done = Object.new.freeze

producer = Thread.new do
Thread.current.abort_on_exception

queries.each do |query|
q.push db.execute(query)
end

q.push done
end

while( ( result = q.pop) != done )
handle_result result
end


you could handle the results in threads too using the same pattern.
the key is here is simply to eliminate the MT aspect of the db handle
usage - for sanity and correctness.

cheers.

a @ http://codeforpeople.com/
 
G

Guillermo.Acilu

Hello,

I have solved the problem. It was something like this:

def mymethod
row =3D myselect.execute(select)
if row.next
Thread.new {mymethod(row.getcursorvalue)}
end
Rescue
puts error
end

As you can see the the variable "row" is local to the method, but when I=20
was including it inside of the thread block, it becomes local of the=20
thread. The database was answering with an error like this "No cursor=20
opened", since the cursor is not valid in the thread context. The Rescue=20
clause was not responding, since the error was introduced before the=20
method was actually called.
you could handle the results in threads too using the same pattern.=20
the key is here is simply to eliminate the MT aspect of the db handle=20
usage - for sanity and correctness.

I am using JRuby 1.1.2 with the Oracle JDBC. The engine is an Oracle 11i=20
running on a separated server, but sometimes I use it in my own MacBook=20
PRO on a linux vmware virtual machine. Do you think it is not thread safe? =

also, why do you think that it is not good to run the queries in parallel?

Cheers,


---
Guillermo Acilu
Senior Engineer, Koiaka GmbH

Koiaka GmbH
Riesserkopfstr. 17=20
82467 Garmisch-Partenkirchen
Tel: +49 (0)8821 9679555=20
Fax: +49 (0)8821 730 9185=20
Mailto:[email protected]
http://www.koiaka.com

Amtsgericht M=FCnchen: HR B 161 041=20
Gesch=E4ftsf=FChrer: Guillermo Acilu=20
Sitz: Garmisch-Partenkirchen

Diese Email kann vertrauliche und/oder rechtlich gesch=FCtzte Informationen=
=20
enthalten. Wenn Sie nicht der richtige Adressat sind oder diese Email=20
irrt=FCmlich erhalten haben, d=FCrfen Sie diese weder benutzen, kopieren,=20
weiterleiten oder irgend eine Ma=DFnahme einleiten, die im Zusammenhang mit=
=20
dem Inhalt dieser Email steht. Informieren Sie bitte sofort den Absender=20
und vernichten Sie die irrt=FCmlich erhaltene Email vollst=E4ndig.
Vielen Dank!

This e-mail message may contain confidential and/or privileged=20
information. If you are not an addressee or otherwise authorized to=20
receive this message, you should not use, copy, disclose or take any=20
action based on this e-mail or any information contained in the message.=20
If you have received this material in error, please advise the sender=20
immediately by reply e-mail and delete this message completely.
Thank you!





From:
"ara.t.howard" <[email protected]>
To:
(e-mail address removed) (ruby-talk ML)
Date:
15.07.2008 18:24
Subject:
Re: Handling exceptions in Threads




If I leave the Thread.abort=5Fon=5Fexception =3D false, the algorithm end= s=20
after
triggering about 10 threads. If I set it to=20
Thread.abort=5Fon=5Fexception =3D
true, the algorithm end abnormally, but without printing any error
message.

I have added the following code at the end of the method called by the
thread:

rescue Exception =3D> error
puts "#{error.class}: #{error.message}"

But I cannot get any error message in the console. I am sure that the
problem is something related with the database, but I do not know=20
how to
solve the problem if I do not see the error message.

Any ideas?


1) STDERR.puts message

stdout bufferes and can get lost


2) it's *highly* unlikely the db handle is thread safe and, if it is,=20
it'll be native thread safe not green thread safe. aka - you will not=20
get anything from using MT to execute your queries.


so, just use producer/consumer to both simplify and speed up your=20
application. for example


q =3D Queue.new

queries =3D list=5Fof=5Fqueries

done =3D Object.new.freeze

producer =3D Thread.new do
Thread.current.abort=5Fon=5Fexception

queries.each do |query|
q.push db.execute(query)
end

q.push done
end

while( ( result =3D q.pop) !=3D done )
handle=5Fresult result
end


you could handle the results in threads too using the same pattern.=20
the key is here is simply to eliminate the MT aspect of the db handle=20
usage - for sanity and correctness.

cheers.

a @ http://codeforpeople.com/
 

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

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top