KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > internetcds > jdbc > tds > CancelController


1 //
2
// Copyright 1998 CDS Networks, Inc., Medford Oregon
3
//
4
// All rights reserved.
5
//
6
// Redistribution and use in source and binary forms, with or without
7
// modification, are permitted provided that the following conditions are met:
8
// 1. Redistributions of source code must retain the above copyright
9
// notice, this list of conditions and the following disclaimer.
10
// 2. Redistributions in binary form must reproduce the above copyright
11
// notice, this list of conditions and the following disclaimer in the
12
// documentation and/or other materials provided with the distribution.
13
// 3. All advertising materials mentioning features or use of this software
14
// must display the following acknowledgement:
15
// This product includes software developed by CDS Networks, Inc.
16
// 4. The name of CDS Networks, Inc. may not be used to endorse or promote
17
// products derived from this software without specific prior
18
// written permission.
19
//
20
// THIS SOFTWARE IS PROVIDED BY CDS NETWORKS, INC. ``AS IS'' AND
21
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
// ARE DISCLAIMED. IN NO EVENT SHALL CDS NETWORKS, INC. BE LIABLE
24
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
// SUCH DAMAGE.
31
//
32

33 package com.internetcds.jdbc.tds;
34
35 /**
36  * This class provides support for canceling queries.
37  * <p>
38  * Basically all threads can be divided into two groups, workers and
39  * cancelers. The canceler can cancel at anytime, even when there is no
40  * outstanding query to cancel. A worker can be in one of 4 states-
41  * <p>
42  * 1) Not doing anything DB related.<br>
43  * 2) currently sending a request to the database. (Note- any time
44  * a request is sent to the DB the DB will send a response. This
45  * means a thread in state 2 must go to state 3.)<br>
46  * 3) waiting for a response from DB<br>
47  * 4) reading the response from DB<br>
48  * <p>
49  * I can easily make it so that only one thread at a time can be in state
50  * 2, 3, or 4.
51  * <p>
52  * The way that a cancel works in TDS is you send a cancel packet to
53  * server. The server will then stop whatever it might be doing and
54  * reply with END_OF_DATA packet with the cancel flag set. (It sends
55  * this packet even if it wasn't doing anything.) I will call this
56  * packet a CANCEL_ACK packet
57  * <p>
58  * All that I really need is to do is make sure that I try to read as
59  * many CANCEL_ACKs as I request and the I make sure that some thread is
60  * out there ready to read any CANCEL_ACKs that i request.
61  * <p>
62  * Clearly if all my worker threads are in state 1 then the cancel
63  * request could be just a nop.
64  * <p>
65  * If I have some worker thread in state 2, 3, or 4 I think I will be fine
66  * if I just make sure that the thread reads until the CANCEL_ACK packet.
67  * <p>
68  * I think I will just have a control object that has one boolean,
69  * readInProgress and two integers, cancelsRequested and
70  * cancelsProcessed.
71  * <p>
72  * <p>
73  * The doCancel() method will-
74  * a) lock the object
75  * b) if there is no read in progress it will unlock and return.
76  * c) otherwise it will send the CANCEL packet,
77  * d) increment the cancelsRequested
78  * e) unlock object and wait until notified that the
79  * cancel was ack'd
80  * <p>
81  * Whenever the worker thread wants to read a response from the DB it
82  * must-
83  * a) lock the control object,<b>
84  * b) set the queryOutstanding flag<b>
85  * c) unlock the control object<b>
86  * d) call the Tds.processSubPacket() method.<b>
87  * e) lock the control object<b>
88  * f) If the packet was a cancel ack it will increment
89  * cancelsProcessed <b>
90  * g) notify any threads that are waiting for cancel acknowledgment<b>
91  * h) unlock the control object.<b>
92  *
93  * @version $Id: CancelController.java,v 1.1 2006/06/23 10:39:04 sinisa Exp $
94  @ @author Craig Spannring
95  */

96 public class CancelController
97 {
98    public static final String JavaDoc cvsVersion = "$Id: CancelController.java,v 1.1 2006/06/23 10:39:04 sinisa Exp $";
99
100
101    boolean awaitingData = false;
102    int cancelsRequested = 0;
103    int cancelsProcessed = 0;
104    
105    public synchronized void setQueryInProgressFlag()
106    {
107       awaitingData = true;
108    }
109
110    private synchronized void clearQueryInProgressFlag()
111    {
112       awaitingData = false;
113    }
114
115    public synchronized void finishQuery(
116       boolean wasCanceled,
117       boolean moreResults)
118    {
119       // XXX Do we want to clear the query in progress flag if
120
// there are still more results for multi result set query?
121
// Whatever mechanism is used to handle outstanding query
122
// requires knowing if there is any thread out there that could
123
// still process the query acknowledgment. Prematurely clearing
124
// could cause data to be thrown out before the thread expecting
125
// the data gets a chance to process it. That could cause the
126
// thread to read some other threads query.
127
//
128
// Is it good enough to just look at the MORERESULTS bit in the
129
// TDS_END* packet and not clear the flag if we have more
130
// results?
131
if (! moreResults)
132       {
133          clearQueryInProgressFlag();
134       }
135
136       if (wasCanceled)
137       {
138          handleCancelAck();
139       }
140
141       // XXX Should we see if there are any more cancels pending and
142
// try to read the cancel acknowledgments?
143
}
144
145
146    public synchronized void doCancel(TdsComm comm)
147       throws java.io.IOException JavaDoc
148    {
149       if (awaitingData)
150       {
151          comm.startPacket(TdsComm.CANCEL);
152          comm.sendPacket();
153          cancelsRequested++;
154
155
156          while(cancelsRequested > cancelsProcessed)
157          {
158             try
159             {
160                wait();
161                // XXX If there are cancels pending but nobody is is
162
// awaiting data on this connection, should we go out
163
// and try to get the CANCELACK packet?
164
}
165             catch(java.lang.InterruptedException JavaDoc e)
166             {
167                // nop
168
}
169          }
170       }
171       else
172       {
173          // if we aren't waiting for anything from
174
// the server then we have nothing to cancel
175

176          // nop
177
}
178    }
179
180
181
182    private synchronized void handleCancelAck()
183    {
184       cancelsProcessed++;
185       notify();
186    }
187 }
188
Popular Tags