Hello Alexis,
 
I went through the same type of questions as you on this forum a while back.
The eventual outcome from which I did not have time to definitely confirm is
that the service client is not thread safe. Apparently it is due to how
axis2 is designed. I could not understand why a service client cannot be
thread safe but never got a satisfactory answer. Anyhow I gave up and in the
end created one AxisConfiguration for many service clients maintained in a
commons pool.
 
I'll be watching this thread with interest since I would like to know why a
service client is not thread safe.
 
Good luck.
 
P

  _____  

From: Alexis Midon [mailto:mi...@intalio.com] 
Sent: 13 March 2009 21:12
To: axis-user
Subject: many threads invoking the same service


Hey there,

I have a few questions about how to use ServiceClient when many threads
invoke the same service. 
In my scenario, multiple threads invoke the same service. The immediate
solution is to instantiate a new ServiceClient for each call.

   client = new ServiceClient();                                     //
[case-1]

But this involves recreating expensive resources like AxisConfiguration. In
addition to these performance considerations, this solution ruins any
programatic configuration that could take place before and that could be
shared among ServiceClient instances.

This is why a ConfigurationContext might be passed to ServiceClient: 

  client = new ServiceClient(configContext, null);           // [case-2]

By doing that each ServiceClient creates its own anonymous service. However
in my case i. the service is the same for all threads and ii. extra tweaking
is done with a ServiceBuilder. So I'd like to share a single service
instance across ServiceClient instances to save resources:

  client = new ServiceClient(configContext, myService);   // [case-3]

Unfortunately, in that case, exceptions are thrown because the AxisConfig
instance already helds a reference on the service instance.

org.apache.axis2.AxisFault: Two services cannot have same name.  A service
with the FOO name already exists in the system.
    at
org.apache.axis2.client.ServiceClient.configureServiceClient(ServiceClient.j
ava:172)
    at org.apache.axis2.client.ServiceClient.<init>(ServiceClient.java:139)

A way to workaround this is to create the ServiceClient with no service, and
then explicitly assign the service:

  client = new ServiceClient(configContext, null);            // [case-4]
  client.setAxisService(myService);

This works pretty well, until a race condition kicks in:

org.apache.axis2.AxisFault: The FOO service, which is not valid, does not
belong to the FOO service group. 
at
org.apache.axis2.context.ServiceGroupContext.getServiceContext(ServiceGroupC
ontext.java:138) 
at
org.apache.axis2.client.ServiceClient.setAxisService(ServiceClient.java:829)


This race condition seems to be fixed in axis2 1.4 by getting a lock on the
AxisConfiguration instance. 

So my questions are:
a. generally speaking what are the best practices/recommendations for the
scenario described here?
b. case-3 and case-4 reveal that the constructor and the setAxisService
method do not have the same behavior. The former fails if the service is
already in the AxisConfiguration, the latter removes the service (if any)
then adds the new service instance. Should this be considered as a bug?
c. but in the first place, why do we need to add the service instance to the
main AxisConfiguration? The service used by the ServiceClient might be
considered as a local object, why should the AxisConfiguration be aware of
it? Its "scope" should be limited and it shouldn't leak to the global
configuration. The static counter for anonymous services [2] sounds like a
hack to workaround a design issue. What am I missing here?

Thanks in advance for your time and answers.

Alexis


[1] ServiceClient, line 175 http://tr.im/hjts
[2] ServiceClient, method createAnonymousService, http://tr.im/hlxm
http://markmail.org/thread/f33xvusqinzh2pm7

Reply via email to