This class provides support for canceling queries.
Basically all threads can be divided into two groups, workers and
cancelers. The canceler can cancel at anytime, even when there is no
outstanding query to cancel. A worker can be in one of 4 states-
1) Not doing anything DB related.
2) currently sending a request to the database. (Note- any time
a request is sent to the DB the DB will send a response. This
means a thread in state 2 must go to state 3.)
3) waiting for a response from DB
4) reading the response from DB
I can easily make it so that only one thread at a time can be in state
2, 3, or 4.
The way that a cancel works in TDS is you send a cancel packet to
server. The server will then stop whatever it might be doing and
reply with END_OF_DATA packet with the cancel flag set. (It sends
this packet even if it wasn't doing anything.) I will call this
packet a CANCEL_ACK packet
All that I really need is to do is make sure that I try to read as
many CANCEL_ACKs as I request and the I make sure that some thread is
out there ready to read any CANCEL_ACKs that i request.
Clearly if all my worker threads are in state 1 then the cancel
request could be just a nop.
If I have some worker thread in state 2, 3, or 4 I think I will be fine
if I just make sure that the thread reads until the CANCEL_ACK packet.
I think I will just have a control object that has one boolean,
readInProgress and two integers, cancelsRequested and
cancelsProcessed.
The doCancel() method will-
a) lock the object
b) if there is no read in progress it will unlock and return.
c) otherwise it will send the CANCEL packet,
d) increment the cancelsRequested
e) unlock object and wait until notified that the
cancel was ack'd
Whenever the worker thread wants to read a response from the DB it
must-
a) lock the control object,
b) set the queryOutstanding flag
c) unlock the control object
d) call the Tds.processSubPacket() method.
e) lock the control object
f) If the packet was a cancel ack it will increment
cancelsProcessed
g) notify any threads that are waiting for cancel acknowledgment
h) unlock the control object.
version: $Id: CancelController.java,v 1.2 2007-10-19 13:21:40 sinisa Exp $ |