Thanks for the detailed reply.  See my comments inline.

  Simon

Rashmi Hunt wrote:

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.

Yes, I understand that the binding can control this.


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.

An Axis2 pure client will need to know the difference between one-way
and two-way server methods because the WSDL generated by the service
will be an in/out MEP for two-way methods but an in-only MEP for
one-way methods (TUSCANY-1658).  If the client tries to make an in/out
Axis2 invocation for WSDL that has an in-only MEP, it will get an
Axis2 exception.  So the difference cannot be hidden from a pure
Axis2 client.

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.

This is a different issue and is not related to @OneWay invocations.
If there is a need for the server to apply thread pooling, then this
applies equally for two-way invocations as well.  In this case,
I think the binding should provide support for thread pooling
within its own code.


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.

OK, we are agreed that this is needed.




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.

>
Yes, and I don't think it would ever be possible for the service side to
know whether a call was coming from an SCA client or a non-SCA client.




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?

Yes, it's a performance concern, both in terms of the extra thread switching
overheads and because of the additional connection resources used at both
ends for a two-way MEP compared with a one-way MEP.




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.

See my comments above.  The pure clients would need to know because the
MEPs are different, and thread pooling on the server would be needed for
both one-way and two-way operations.



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]




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

Reply via email to