Thank you for the response. the proposed implementation will not insert non
blocking
interceptor for every service wire. The proposed logic inserts a
NonBlockingInterceptor
 on the service wire only if binding indicates it and the operation is
nonblocking(oeway).
It's up the binding to decide if they want nonblockinginterceptor on service
wire or not.
For e.g JMS binding doesn't need non blocking interceptor at the service
wire, since
there is already a thread involved at the service natively. However SCA
default or WS
binding may want to have this interceptor for the service wire.


> I'm not convinced that this interceptor should be added on the service
> side.
> If the binding used for the call supports a nonblocking MEP and wire
> protocol,
> then a non-SCA caller can use this MEP to achieve nonblocking semantics.


If we take my original reason of pure client case, say for e.g pure WS
client
sending a request to SCA webservice, how can current WS Service binding
implementation achieve oeway call?   In WS service binding impl, there is
no thread involved neither at the WS binding service side nor at axis2
service
side. Then the burden lies on pure client, where WS client (pure) client
needs
send a request blocking/non blocking from the client side which brings to a
question why pure client needs to know SCA symantics and also needs to know
if
the service operation is oneway (nonBlocking) and send requests accordingly
using
different axis2 APIs? Same issue for other pure clients as well.

Another main reason to insert the NonBlockingInterceptor at the service, is
to
manage the thread pool at the service (intra or inter composite service).
Depending on the async load or number of async requests
coming to the service, there may be a need to manage pool of threads
(workmanager threads)
on the service assigning different workmanager per service.  Currently
Tuscany's code doesn't
allow to do this since there is no thread (nonBlocking interceptor) for
oneway calls on
the service and hence thread pool doesn't even come into picture.

> If the binding only supports two-way blocking MEP, then we get into the
> following situation:
> 1. An SCA client inserts a nonblocking interceptor in case it's talking to
> a
>     non-SCA service



Currently,  Tuscany which inserts nonblockingInterceptor on reference wire
during
composite start to support nonBlocking calls. Most bindings, based on it's
protcol support,
may/may not want to spin a thread in their reference binding implementation.
Instead they
just rely on Tuscany's nonBlockingInterceptor to handle oneway call.




> 2. An SCA service inserts a nonblocking interceptor in case it's being
> called
>     from a non-SCA client



This is the current proposal, to insert nonblocking interceptor on service
wire. A note here is,
as per Tuscany's infrastructure, nonblockingInterceptor can be inserted only
during composite
start,  not at the runtime based on whether caller is SCA or non SCA client.
Such infrastructure
support doesn't exist today.



> 3. When an SCA client talks to an SCA service, both the client and the
> service
>     will have nonblocking interceptors and we will do a thread switch at
> both ends.


I don't much like this case either.  Even if there is thread involved at the
reference as well
as at the service, what would be the concern? Is it a performance concern or
some other reason?



> I don't much like case 3.  For this case, the best place for the thread
> switch
> is on the client side, because this does not block the client while the
> wire
> protocol messages (two-way MEP) are being exchanged.  This allows cases 1
> and
> 3 to be supported.






>  For case 2, it would be necessary for the non-SCA client
> to be able to spin off a thread if it wants to achieve nonblocking
> semantics.


Same comment as above. Why the burden should be on the pure clients to spin
a thread at the client?
Why they need to know they are calling SCA @oneway operation knowing SCA
symantics? Also having
thread only at the reference will not fullfill the thread pool requirement I
stated above.



> Note that it is not an error or a violation of the SCA spec if the call
> executes
> in a blocking manner in case 2.  Specifying the @OneWay annotation allows
> the
> method to be invoked in a nonblocking manner, but does not require this.
>
> If we agree that the interceptor should always go on the client side, then
> we should remove the supportsAsyncOneWayInvocation() method from the
> service
> provider SPI.

Not sure I agree on removing this until there is alternate solutions for the
two requirements
stated above.
Regards
Rashmi


  Simon

Rashmi Hunt (JIRA) wrote:

>      [
https://issues.apache.org/jira/browse/TUSCANY-1674?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel]
>
> Rashmi Hunt updated TUSCANY-1674:
> ---------------------------------
>
>     Attachment: RuntimeWireImpl.java
>
> This patch is applied on top of Tuscany revision  r572771
>
>
>>Missing NonBlockingInterceptor on service wire
>>----------------------------------------------
>>
>>                Key: TUSCANY-1674
>>                URL: https://issues.apache.org/jira/browse/TUSCANY-1674
>>            Project: Tuscany
>>         Issue Type: Bug
>>           Reporter: Rashmi Hunt
>>        Attachments: RuntimeWireImpl.java
>>
>>
>>The reason why NonBlockingInterceptor is needed on the service wire as
well is, if there is no nonBlockingInterceptor at service wire and if the
service is invoked not from a reference then there is no asynch support even
if the call is non blocking. For e.g  if a pure webservice client (or any
pure client) is sending a request to a non blocking service call,  since
Tuscany code is currently missing a nonBlockingInterceptor on the service
wire, there is no async support for this case, even though the service
operation is marked as non-blocking.
>>Solution is straightforward. Add NonBlockingInterCeptor on service wire in
RuntimeWireImpl.initInvocationChains() for the service wire clause
>>               Binding serviceBinding = wireTarget.getBinding();
>>                if (operation.isNonBlocking()) {
>>                    addNonBlockingInterceptor(service, serviceBinding,
chain);
>>                }
>>And add a new addNonBlockingInterceptor() function which takes params
service, serviceBinding, chain
>>    /**
>>     * Add a non-blocking interceptor if the service binding needs it
>>     *
>>     * @param service
>>     * @param binding
>>     * @param chain
>>     */
>>    private void addNonBlockingInterceptor(ComponentService service,
Binding binding, InvocationChain chain) {
>>        ServiceBindingProvider provider =
((RuntimeComponentService)service).getBindingProvider(binding);
>>        if (provider != null) {
>>            boolean supportsAsyncOneWayInvocation = false;
>>            if (provider instanceof ServiceBindingProvider2) {
>>                supportsAsyncOneWayInvocation =
((ServiceBindingProvider2)provider).supportsAsyncOneWayInvocation();
>>            } else {
>>                // Must be an old provider that doesn't have this method.
If this is a old provider keep the behavior
>>                // as is where there is no nonBlockingInterceptor on the
service wire. If a binding provider needs a
>>                // nonBlocking interceptor, it would have been implemented
ServiceBindingProvider2 and indicated
>>                // supportsAsyncOneWayInvocation accordingly
>>                supportsAsyncOneWayInvocation = true;
>>            }
>>            if (!supportsAsyncOneWayInvocation) {
>>                chain.addInterceptor(new
NonBlockingInterceptor(workScheduler));
>>            }
>>        }
>>    }
>
>



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to