Mike Matrigali wrote:
I am looking a problems caused by interrupts being delivered to to
Derby threads from outside Derby code (for example see DERBY-151). In
all of the cases that I have had to
do support on the application didn't actually want to interrupt Derby,
and often did not even know their code (or some other code they had
embedded) was doing the interrupt. As the test case in DERBY-151 shows
it is very easy to cause this, just call Thread.
Prior to our use of channel based I/O in the logging system and the
data base I/O these interrupts would not affect the I/O at all. Now
if an
interrupt is delivered to a thread that will call Derby code before the
thread's isInterrupted flag is cleared any channel based I/O will fail.
So customers moving up to later Derby versions are seeing this as a
regression.
So after looking at this a little should Derby try to do it's I/O
somehow, basically somehow ignoring the interrupt? I think the only
way to continue would be to clear the interrupt and then doing work
to either reget the channel, and possibly reopen the file. This was
the path was making my way down at first, but then wondered if this was
a good behavior for an embedded application. Any opinions?
Hi Mike,
I think somehow ignoring the interrupt would be fine. Doesn't that take
us back to the previous behavior?
If it is possible, maybe something like this could be done:
a) When getting ClosedByInterruptException, clear interrupted flag, and
redo operation.
b) After a successful completion, set interrupted flag again and continue.
c) Define "safe" interruption points.
d) Determine if the interrupted flag will affect us in any other way.
The interruption points (c) don't have to be in Derby, i.e. Derby
completes whatever operation it is doing and it will then be up to the
application to stop by not sending any more requests to Derby. They can
also be in Derby, but then we must identify locations where it is
safe/convenient to abort. For instance, maybe we could exploit the
existing timeout functionality for this, by also checking if the thread
is interrupted?
I'm a bit skeptical about having Thread.interrupt() stop Derby in
arbitrary places, but maybe that can be done by throwing an exception?
Feel free to correct me, I haven't spent a lot of time studying this in
detail.
--
Kristian
In most cases if
Derby gets an interrupt error it is going to treat it as unrecoverable
and shut down the database. The errors in this case could definitely
be improved, as they mostly point the wrong cause and lead user to think
the db is corrupted. In all the interrupt based shutdowns that I have
seen the db will boot fine as long as the booting thread has cleared the
interrupted flag. Unfortunately I think it would be a major project to
figure out how to only affect the current thread in such a I/O failure
as there are low level cross thread dependencies on the I/O working so
it is not as simple as just failing the current thread (especially
hard are reads and writes to the database recovery log which may
contain work
for more than just the current thread).