The thing is that in my case I have one ServiceClient *per* thread. None of
them are accessed by different threads.
Alexis
On Fri, Mar 13, 2009 at 2:35 PM, Paul French wrote:
> 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.java:172)
> at org.apache.axis2.client.ServiceClient.(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
>