Hi Mike, thanks for looking at this!
> I was wondering if you have a high level
> goal. Basically what should derby do when it encounters an
I started off merely trying to make the new IO pieces stand up as well
as the old I/O, but I guess my ambitions grew a bit as I found many
things could bring Derby down..
My thinking so far is that Derby should:
a) avoid having to shut down if a thread has been interrupted
b) throw something when it finds the thread has been interrupted,
preferably as soon as possible, but not before the code has arrived at
a "safe place", so we can avoid Derby shutting down.
> I think it should always throw some sort of error back to caller,
> and would be nice if the error or the nested error indicated clearly
> that it is being thrown because of a thread interrupt. Many times
> when supporting this issue it takes awhile for the user to realize
> that they are the ones generating the interrupt.
Agreed. So far I have been thinking of just using the connection level error 08000,
wrapping the original NIO channel exception, or InterruptedException.
This should make it clear what has happened, and unwrapping the exception would
show where Derby detected it.
> I think the error should not be database level, and with your retry
> on I/O and log it seems like we can avoid that.
That's what I am trying to achieve, yes.
> I am not sure if it should be session or statement level, I am
> leaning to it being session level, but would like to see a
> discussion. I know often users are doing the interrupt to stop a
The existing code throws session level error 08000 already in many
places, and I felt it's OK to require that the user reconnect when she
has done something as drastic as interrupting the thread
> Ultimately do you plan on always reenabling the interrupt after
> retrying or getting to a safe place?
I am still pondering this question. I think that by the principle of
least surprise to the user, we should set the interrupted flag of the
thread again just before we throw the exception from the "safe place".
Note: the exisiting code does not resurrect the
thread's interrupted flag when it detects an interrupt of a wait and throws
StandardException.interrupt. (wait would have cleared the flag).
An imminent problem is where would the "safe place" be? It would be
nice to avoid having to check in all JDBC API methods before we
return if Derby has been interrupted during the API call, but I am not
yet sure if I am able to determine conclusively which API code paths
could lead to Derby being interrupted.. One approach would be to throw
as "soon as possible" from a "safe place" on the stack above the
method that saw the interrupt, but it may be hard to always determine
where that would be in all cases. I am open to suggestions here
The current experimental patch mostly doesn't throw yet (I didn't get
that far) - it just makes a note that an interrupt was detected. Nor
does it resurrect the interrupted flag when it does throw - since I
was still torn on this.
> We should definitely throw an error in the case of an interrupt
> during a lock wait, this seems like the one valid case to send an
> interrupt to derby if a user thinks it is waiting too
> long. Hopefully you can code it to handle it, do processing, get to
> safe spot and then throw an error indicating a real user interrupt
> during a wait.
Yes, I am trying to do exactly that, agreed.
I also would like interrupts on queries to be detected no later that
at the place where we check for query time-outs already,
> Something to think about in the error throwing is the background
> thread. What should we do if it encounters an interrupt. Throwing an
> error there might shutdown the db, i am not sure what it does at top
> level with an error.
Right. A priori, I thought the most common use case would be user
threads getting interrupted, but I'll look into that. One approach
could be to shutdown, or possibly try to make it impervious and ignore