writeObject now throws XmlRpcException.

If an Error occurs while writing a response, a valid error message is generated.
This commit is contained in:
hns 2001-01-30 18:41:57 +00:00
parent 9a1f750707
commit ef36481edd
5 changed files with 50 additions and 31 deletions

View file

@ -11,15 +11,15 @@ public class Benchmark implements Runnable {
XmlRpcClient client;
static String url;
static int clients = 8;
static int loops = 200;
static int clients = 16;
static int loops = 100;
int gCalls = 0, gErrors = 0;
Date date;
public Benchmark () throws Exception {
client = new XmlRpcClient (url);
client = new XmlRpcClientLite (url);
Vector args = new Vector ();
// Some JITs (Symantec, IBM) have problems with several Threads

View file

@ -239,7 +239,7 @@ public abstract class XmlRpc extends HandlerBase {
/**
* Writes the XML representation of a supported Java object to the XML writer.
*/
void writeObject (Object what, XmlWriter writer) {
void writeObject (Object what, XmlWriter writer) throws XmlRpcException {
writer.startElement ("value");
if (what == null) {
// try sending experimental <ni/> element
@ -295,7 +295,7 @@ public abstract class XmlRpc extends HandlerBase {
}
writer.endElement ("struct");
} else
throw new RuntimeException ("unsupported Java type: " + what.getClass ());
throw new XmlRpcException (0, "Java class not supported in XML-RPC: " + what.getClass ());
writer.endElement ("value");
}
@ -542,6 +542,7 @@ public abstract class XmlRpc extends HandlerBase {
public XmlWriter (StringBuffer buf, String enc) {
this.buf = buf;
buf.setLength (0);
this.enc = enc;
// get name of encoding for XML prolog
String encName = encodings.getProperty (enc, enc);

View file

@ -24,6 +24,8 @@ public class XmlRpcClient implements XmlRpcHandler {
// pool of worker instances
Stack pool = new Stack ();
int workers = 0;
int asyncWorkers = 0;
// average roundtrip of this method call. This is used to decide if
// additional threads are needed or not in async mode
@ -82,7 +84,7 @@ public class XmlRpcClient implements XmlRpcHandler {
* @exception IOException: If the call could not be made because of lower level problems.
*/
public Object execute (String method, Vector params) throws XmlRpcException, IOException {
Worker worker = getWorker ();
Worker worker = getWorker (false);
long start = System.currentTimeMillis ();
try {
Object retval = worker.execute (method, params);
@ -90,7 +92,7 @@ public class XmlRpcClient implements XmlRpcHandler {
roundtrip = (int) ((roundtrip*4)+(end-start))/5;
return retval;
} finally {
releaseWorker (worker);
releaseWorker (worker, false);
}
}
@ -101,13 +103,13 @@ public class XmlRpcClient implements XmlRpcHandler {
*
*/
public void executeAsync (String method, Vector params, AsyncCallback callback) {
if (workers > 2) {
if (asyncWorkers > 2) {
enqueue (method, params, callback);
return;
}
Worker worker = null;
try {
worker = getWorker ();
worker = getWorker (true);
worker.executeAsync (method, params, callback);
} catch (IOException iox) {
// make a queued worker that doesn't run immediately
@ -116,14 +118,20 @@ public class XmlRpcClient implements XmlRpcHandler {
}
synchronized Worker getWorker () throws IOException {
synchronized Worker getWorker (boolean async) throws IOException {
try {
Worker w = (Worker) pool.pop ();
workers += 1;
if (async)
asyncWorkers += 1;
else
workers += 1;
return w;
} catch (EmptyStackException x) {
if (workers < maxThreads) {
workers += 1;
if (async)
asyncWorkers += 1;
else
workers += 1;
return new Worker ();
}
throw new IOException ("XML-RPC System overload");
@ -133,12 +141,15 @@ public class XmlRpcClient implements XmlRpcHandler {
/**
* Release possibly big per-call object references to allow them to be garbage collected
*/
synchronized void releaseWorker (Worker w) {
synchronized void releaseWorker (Worker w, boolean async) {
w.result = null;
w.call = null;
if (pool.size() < 20 && !w.fault)
pool.push (w);
workers -= 1;
if (async)
asyncWorkers -= 1;
else
workers -= 1;
}
@ -155,8 +166,8 @@ public class XmlRpcClient implements XmlRpcHandler {
synchronized CallData dequeue () {
if (first == null)
return null;
// if (workers > 2 && workers*4 > roundtrip)
// return null;
if (asyncWorkers > 4 && asyncWorkers*4 > roundtrip)
return null;
CallData call = first;
if (first == last)
first = last = null;
@ -187,11 +198,9 @@ public class XmlRpcClient implements XmlRpcHandler {
public void run () {
while (call != null) {
runAsync (call.method, call.params, call.callback);
// System.err.println (workers+" ---- "+ roundtrip);
call = dequeue ();
// if (call != null) System.err.print (".");
}
releaseWorker (this);
releaseWorker (this, false);
}
void runAsync (String method, Vector params, AsyncCallback callback) {
@ -203,8 +212,9 @@ public class XmlRpcClient implements XmlRpcHandler {
if (callback != null)
callback.handleResult (res, url, method);
} catch (Exception x) {
if (callback != null)
if (callback != null) try {
callback.handleError (x, url, method);
} catch (Exception ignore) {}
}
long end = System.currentTimeMillis ();
roundtrip = (int) ((roundtrip*4)+(end-start))/5;
@ -218,8 +228,7 @@ public class XmlRpcClient implements XmlRpcHandler {
if (strbuf == null)
strbuf = new StringBuffer ();
else
strbuf.setLength (0);
XmlWriter writer = new XmlWriter (strbuf);
writeRequest (writer, method, params);
byte[] request = writer.getBytes();
@ -272,7 +281,7 @@ public class XmlRpcClient implements XmlRpcHandler {
/**
* Generate an XML-RPC request from a method name and a parameter vector.
*/
void writeRequest (XmlWriter writer, String method, Vector params) throws IOException {
void writeRequest (XmlWriter writer, String method, Vector params) throws IOException, XmlRpcException {
writer.startElement ("methodCall");
writer.startElement ("methodName");

View file

@ -41,14 +41,20 @@ public class XmlRpcClientLite extends XmlRpcClient {
}
synchronized Worker getWorker () throws IOException {
synchronized Worker getWorker (boolean async) throws IOException {
try {
Worker w = (Worker) pool.pop ();
workers += 1;
if (async)
asyncWorkers += 1;
else
workers += 1;
return w;
} catch (EmptyStackException x) {
if (workers < maxThreads) {
workers += 1;
if (async)
asyncWorkers += 1;
else
workers += 1;
return new LiteWorker ();
}
throw new IOException ("XML-RPC System overload");

View file

@ -96,8 +96,7 @@ public class XmlRpcServer {
inParams = new Vector ();
if (strbuf == null)
strbuf = new StringBuffer ();
else
strbuf.setLength (0);
long now = System.currentTimeMillis ();
try {
@ -150,7 +149,11 @@ public class XmlRpcServer {
String message = x.toString ();
// check if XmlRpcException was thrown so we can get an error code
int code = x instanceof XmlRpcException ? ((XmlRpcException) x).code : 0;
writeError (code, message, writer);
try {
writeError (code, message, writer);
} catch (XmlRpcException xrx) {
// won't happen, we just sent a struct with an int and a string
}
try {
result = writer.getBytes ();
} catch (UnsupportedEncodingException encx) {
@ -173,7 +176,7 @@ public class XmlRpcServer {
/**
* Writes an XML-RPC response to the XML writer.
*/
void writeResponse (Object param, XmlWriter writer) {
void writeResponse (Object param, XmlWriter writer) throws XmlRpcException {
writer.startElement ("methodResponse");
// if (param == null) param = ""; // workaround for Frontier bug
writer.startElement ("params");
@ -187,7 +190,7 @@ public class XmlRpcServer {
/**
* Writes an XML-RPC error response to the XML writer.
*/
void writeError (int code, String message, XmlWriter writer) {
void writeError (int code, String message, XmlWriter writer) throws XmlRpcException {
// System.err.println ("error: "+message);
Hashtable h = new Hashtable ();
h.put ("faultCode", new Integer (code));