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]
