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.java: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(ServiceGroupContext.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