Synchronizing each method is insufficient. Assume you synchronize each method and use one Call object. Follow this scenario:
- Thread T1 sets the endpoint to X
- Thread T2 sets the endpoint to Y
- T1 calls stub.a synchronously but setting the endpoint is outside any synchronization so it calls T2's endpoint.

Russell Butek
[EMAIL PROTECTED]

Please respond to [EMAIL PROTECTED]

To: "'[EMAIL PROTECTED]'" <[EMAIL PROTECTED]>
cc: "'[EMAIL PROTECTED]'" <[EMAIL PROTECTED]>
Subject: RE: WSDL2Java: generated client stub and performance issues




I believe the code is the way that it is to allow the use of a Stub object from multiple threads, each having its own Call object.  It is on my TODO list to revisit the way this all works because:

- I believe that synchronizing the methods of the Stub would provide for the thread safety that we need with little performance penalty (uncontested locks are *very* fast in the JVM).

- The way that it is now is complicated and, as you pointed out, inefficient.

The way I envision the stub is to have a single Call object, initialized at Stub creation with the type mappings, used throughout the class.  I haven't prototyped this yet however, although this is the way the code used to work a long time ago.  Russell made the changes back then.  The big issue with this is the reuse of the Call object - what problems will that cause (if any).

Russell, I know we had a discussion about revamping the way we allocate the Call objects in the stub.  Do you remember when that was (or have that thread archived)?

--
Tom Jordahl
Macromedia


-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]]
Sent: Tuesday, July 02, 2002 8:50 AM
To: [EMAIL PROTECTED]
Cc: [EMAIL PROTECTED]
Subject: WSDL2Java: generated client stub and performance issues


Hello.

Two performance issues:

1. I just wonder why in generated stub code the call objects aren't cached?
I.e. the follow code take place during every (even subsequently)

function call:

// In function  private org.apache.axis.client.Call createCall() throws
java.rmi.RemoteException {

          org.apache.axis.client.Call call =
          (org.apache.axis.client.Call) super.service.createCall
();
if (super.maintainSessionSet) {
          call.setMaintainSession(super.maintainSession);
          }
          if (super.cachedUsername != null) {

          call.setUsername(super.cachedUsername);
          }
          if (super.cachedPassword != null) {

          call.setPassword(super.cachedPassword);
          }
          if (super.cachedEndpoint != null) {

          call.setTargetEndpointAddress(super.cachedEndpoint);
          }
          if (super.cachedTimeout != null) {

          call.setTimeout(super.cachedTimeout);
          }
          java.util.Enumeration keys = super.cachedProperties.keys();
          while (keys.hasMoreElements()) {
            String key = (String) keys.nextElement();
            if(call.isPropertySupported(key))

            call.setProperty(key, super.cachedProperties.get(key));
            else
call.setScopedProperty(key,
super.cachedProperties.get(key));
          }
// In function public Hugo foo(...)
javax.xml.namespace.QName p0QName = new javax.xml.namespace.QName

("", "bar");
call.addParameter(p0QName, new javax.xml.namespace.QName

("http://schemas.xmlsoap.org/soap/encoding/", "string"),
java.lang.String.class, javax.xml.rpc.ParameterMode.IN);

call.setReturnType(new javax.xml.namespace.QName
("urn:HugoNameSpace", "Hugo"));
        call.setUseSOAPAction(true);
        call.setSOAPActionURI("");
        call.setOperationStyle("rpc");
        call.setOperationName(new javax.xml.namespace.QName
("urn:FooNamespace", "foo"));

One could simple cache the call object(s) (in the same way as
serializer/deserializer) in Hashtable or
in Array (if for each method an unique index in the array is assigned).

2. Type registration take place not untill the first call is made. That's
why the performance of first call isn't ideal.
(In my case first call= 5 second, second call 2.5 second)

I would like to initialize all the needed stuf in the startup phase of
the client.

To achive it now, I have define a dummy method and call it, because
the function createCall is
      private and cannot be called directly from the client.
Any comments?

Thank you.
David Ostrovsky

Reply via email to