Thank you for this supersonic response. I will try it for sure.

Thanks again
Marcin Skladaniec


On 13/10/2004, at 4:32 PM, Jason Wyatt wrote:

Hi Marcin,
 
I had a similar problem with xmlrpc, no way to set the timeout, so I wrote a utility class to add this. The other thing I wanted was for any exceptions that were caught in the thread that actually performs the xmlrpc.execute to be passed to the object that created the thread, and then rethrown. I don't know if there was an easier way to do this, but it seems to work OK. I've been using this in production on several projects with no major problems so far.
 
Code follows... forgive the lack of docco :)
 
Regards
Jason
 
--
Falun Gong: A peaceful meditation practice under persecution in China
http://www.falundafa.org


Truth - Compassion - Forbearance
 
 
package common.util.xmlrpc;
 
/**
 * <p>Title:  TimedXmlRpcClient</p>
 * <p>Description: This XmlRpcClient simply adds a connection timeout, after
 *  which if the XML-RPC call did not complete, an IOException is thrown.</p>
 * <p>Copyright: Copyright (c) 2002</p>
 * <p>Company: </p>
 * @author  Jason Wyatt
 * @version 1.0
 */

import java.util.Vector;
import java.io.IOException;
import java.net.MalformedURLException;
 
import org.apache.xmlrpc.*;
 
public class TimedXmlRpcClient implements Runnable
{
  private XmlRpcClient xmlRpcClient;
  private String hostname;
  private int ip;
  private int connectTimeout=30000; // 30 seconds default
  private String remoteFunction;
  private Vector params;
  private Object returnValue=null;
  private XmlRpcException xmlRpcException=null;
  private IOException ioException=null;
  private MalformedURLException malformedURLException=null;
 
  TimedXmlRpcClient(String hostname, int ip, int connectTimeout, String remoteFunction, Vector params)
  {
    this.hostname=hostname;
    this.ip=ip;
    this.connectTimeout=connectTimeout;
    this.remoteFunction=remoteFunction;
    this.params=params;
  }
 
 
 public static Object execute(String hostname, int ip, int connectTimeout, String remoteFunction, Vector params) throws XmlRpcException,
    IOException, MalformedURLException
  {
    TimedXmlRpcClient client=new TimedXmlRpcClient(hostname,ip,connectTimeout,remoteFunction,params);
 
    Thread t = new Thread(client);
    t.start();
    try
    {
      t.join(connectTimeout); // exit the thread once it has completed, or after timeout
    }
    catch (InterruptedException ex)
    {
    }
 
    // if an exception occurred while executing the remote call, throw it again
    // from here
    IOException ex=client.getIOException();
    if(ex!=null)
      throw ex;
 
    XmlRpcException ex2=client.getXmlRpcException();
    if(ex2!=null)
      throw ex2;
 
    MalformedURLException ex3=client.getMalformedURLException();
    if(ex3!=null)
      throw ex3;
 
    Object returnVal=client.getReturnVal();
    if(returnVal==null)
     throw new IOException("Operation timed out");
 
    return returnVal;
  }
 
 
  public void run()
  {
    try
    {
      xmlRpcClient=new XmlRpcClient(hostname, ip);
      returnValue=xmlRpcClient.execute(remoteFunction, params);
    }
    catch (MalformedURLException ex)
    {
      malformedURLException=ex;
    }
    catch (IOException ex2)
    {
      ioException=ex2;
    }
    catch(XmlRpcException ex3)
    {
      xmlRpcException=ex3;
    }
  }
 
  public Object getReturnVal()
  {
    return returnValue;
  }
 
  public XmlRpcException getXmlRpcException()
  {
    return xmlRpcException;
  }
 
  public IOException getIOException()
  {
    return ioException;
  }
 
  public MalformedURLException getMalformedURLException()
  {
    return malformedURLException;
  }

  public static void main(String[] args)
  {
    try
    {
      Vector params=new Vector();
      params.add( "select table_name from all_tables");
      TimedXmlRpcClient.execute("localhost",32000,5,"queryHandler.sqlQuery",params);
    }
    catch (Exception ex)
    {
      System.err.println("Error calling TimedXmlRpcClient:");
      ex.printStackTrace();
    }
  }
}
 
 
 
 


From: Marcin Skladaniec [mailto:[EMAIL PROTECTED]
Sent: Wednesday, 13 October 2004 4:02 PM
To: [EMAIL PROTECTED]
Subject: XmlRpc Client won't die ...

Hello !
I have a <x-tad-smaller>XmlRpcClient</x-tad-smaller> executing an rpc method on very unreliable server. I have to force quit <x-tad-smaller>XmlRpcClient.execute() from time to time, but I can't. I have even created a separate Thread for it, and I'm quitting the Thread after timeout. It is working but not always, when server receives xmlrpc request and freezes without any sign of life my thread is uninterruptible. Is my approach to this problem right or am I missing something ? Does anyone created some other workaround for missing timeout in XmlRpc framework ?</x-tad-smaller>


<x-tad-smaller> This is the impoortant part of my code:</x-tad-smaller>


<x-tad-smaller>public SpacialThread(String pRemoteDatabaseURL, String pXmlRpcMethod, Vector pXmlRpcParameters) {</x-tad-smaller>
<x-tad-smaller>super();</x-tad-smaller>

<x-tad-smaller>xmlRpcResponse = null;</x-tad-smaller>

<x-tad-smaller>xmlRpcMethod = pXmlRpcMethod;</x-tad-smaller>
<x-tad-smaller>xmlRpcParameters = pXmlRpcParameters;</x-tad-smaller>
<x-tad-smaller>// See setResponse</x-tad-smaller>
<x-tad-smaller>hasReceivedResponse = false;</x-tad-smaller>
<x-tad-smaller>hasBeenInterrupted = false;</x-tad-smaller>

<x-tad-smaller>try {</x-tad-smaller>
<x-tad-smaller>client = new XmlRpcClient(pRemoteDatabaseURL);</x-tad-smaller>
<x-tad-smaller>} catch (java.net.MalformedURLException e) {</x-tad-smaller>
<x-tad-smaller>logger.error("(hash: " + hashCode() + "): java.net.MalformedURLException thrown:\n" </x-tad-smaller>
<x-tad-smaller>+ e);</x-tad-smaller>
<x-tad-smaller>}</x-tad-smaller>

<x-tad-smaller>start();</x-tad-smaller>
<x-tad-smaller>}</x-tad-smaller>


<x-tad-smaller>public void run() {</x-tad-smaller>
<x-tad-smaller>try {</x-tad-smaller>
<x-tad-smaller>// This is a blocking call...</x-tad-smaller>
<x-tad-smaller>logger.debug("(hash: " + hashCode() + "): Attempting Xml Rpc transaction.");</x-tad-smaller>
<x-tad-smaller>// Set response explicitly (this should be thread safe?)</x-tad-smaller>
<x-tad-smaller>Object response = client.execute(xmlRpcMethod, xmlRpcParameters);</x-tad-smaller>
<x-tad-smaller>setResponse(response);</x-tad-smaller>

<x-tad-smaller>if (isInterrupted()) {</x-tad-smaller>
<x-tad-smaller>hasBeenInterrupted = true;</x-tad-smaller>
<x-tad-smaller>logger.error("(hash: " + hashCode() + "): Xml Rpc transaction interrupted explicitly. Exiting. (Communication with remote abandoned)");</x-tad-smaller>
<x-tad-smaller>} else {</x-tad-smaller>
<x-tad-smaller>logger.debug("(hash: " + hashCode() + "): Returned from Xml Rpc transaction.");</x-tad-smaller>
<x-tad-smaller>}</x-tad-smaller>

<x-tad-smaller>} catch (Exception e) {</x-tad-smaller>
<x-tad-smaller>// Something else gone wrong... log the error and leave the exception for reference.</x-tad-smaller>
<x-tad-smaller>logger.error("(hash: " + hashCode() + "): Xml Rpc transaction interrupted abormally. Exiting. (Communication with remote abandoned)");</x-tad-smaller>
<x-tad-smaller>setException(e);</x-tad-smaller>
<x-tad-smaller>} finally {</x-tad-smaller>
<x-tad-smaller>// Regardless of the situation, clean up and release the network resources (hopefully)</x-tad-smaller>
<x-tad-smaller>logger.debug("(hash: " + hashCode() + "): Xml Rpc transaction finilizing - releasing resources.");</x-tad-smaller>
<x-tad-smaller>client = null;</x-tad-smaller>
<x-tad-smaller>}</x-tad-smaller>
<x-tad-smaller>}</x-tad-smaller>

<x-tad-smaller>Cheers</x-tad-smaller>
<x-tad-smaller>Marcin Skladaniec</x-tad-smaller>

Reply via email to