4 Replies Latest reply on Jun 3, 2005 5:12 PM by ovidiu.feodorov

    Delegate implementation

    ovidiu.feodorov

      When implementing server delegates, we keep bumping in these "we don't handle this on the server" type of methods.

      Examples:
      - ConnectionDelegate.getExceptionListener()
      - ConnectionDelegate.setExceptionListener()
      - SessionDelegate.delivered()
      - SessionDelegate.acknowledgeSession()
      - SessionDelegate.createMessage()
      - SessionDelegate.createBytesMessage(), etc.

      There is no reason to have noop server-side implementations for these methods. They are only useful on the client and they are fielded there. I makes sense to split each delegate interface in two parts: a client-side delegate interface that groups methods handled on the client and a server-side delegate interface, which exposes calls that must go to the server.

      The dynamic proxy delegate implements both interfaces, but the corresponding server-side delegate implements only the server interface.

      This is what I did for consumer: there is a ConsumerDelegate interface and (it used to be) an AcknowledgmentHandler interface. The client-side proxy implements both, while the ServerConsumerDelegate used to implement AcknowledgmentHandler.

        • 1. Re: Delegate implementation
          timfox

          Hey Ovidiu-

          This is an interesting idea.

          Would it not cause problems though in being able to move interceptors from the client stack to the server stack?

          E.g. if we wanted a really thin client - e.g. if the client had limited memory, we might want to move the session interceptor from the client stack to the server stack, so we didn't use memory holding unacked messages for a session.

          I don't know how realistic this is, but if we wanted to do this then both client and server delegates need to implement the same interface(s).

          If we had separate interfaces then client and server interceptors wouldn't necessarily be interchangeable ??

          • 2. Re: Delegate implementation
            ovidiu.feodorov

            I don't think that both client and server delegates need to implement the same interface in order to preserve our freedom to move interceptors from client to server and back.

            Consider the case of a generic delegate XDelegate with three methods a(), b() and c(). Out of these, two methods (a() and b()) are handled by interceptors and one (c()) is handled by the server delegate. Currently our design has both the client delegate (the dynamic proxy) and the server delegate implement XDelegate. On the server delegate, a() and b() are noops.

            Nothing in this arrangement specifies where the interceptors are - on the client or on the server -. The only important thing is that there are interceptors that handle a() and b() somewhere between the client delegate and the server delegate. They can migrate from client to the server and back, provided the fact that a() and b() must be handled by interceptors doesn't change.

            What I am proposing is to have two interfaces

            XClientDelegate
            {
             a()
             b()
            }
            
            XServerDelegate
            {
             c()
            }
            


            The client-side dynamic proxy will implement both XClientDelegate and XServerDelegate. The interceptors (regardless of their location, client or server) will handle a() and b(). The server delegate only implements XServerDelegate, so there's need for noops on the server. To make things even clearer, we could use the name "InterceptorOperations" instead of "XClientDelegate".


            Of course, there is another possibility that we completely get rid of server delegates and we handle everything with interceptors, which will render the problem completely irrelevant. However, I am not convinced yet that using server delegates is a bad idea. They offer a natural way to maintain state, for example.



            • 3. Re: Delegate implementation
              timfox

              I think I'm understanding.

              So XClientDelegate contains those operations that you know are going to be handled by interceptors somewhere (they can be on the client stack or the server stack)

              XServerDelegate contains those operations that you know are never handled by interceptors.

              I agree this doesn't prevent movement of interceptors from client stack to server stack.

              But what if you have an operation (e.g. createMessage) that's only declared in XClientDelegate since it's handled by an interceptor, but you decide (for some strange reason) you actually want to handle it on the server.

              Then both XClientDelegate and XServerDelegate need to change.

              Also you might have an operation that's sometimes handled by an interceptor and sometimes by the server depending on some application state. In which case it needs to be duplicated in both interfaces.

              e.g.

              public class MyInterceptor ....
              {
              public Object invoke(Invocation i)
              {
              
              if (thinClient)
              {
              //Handle the invocation here
              return handleHere();
              }
              else
              {
              //Handle on server
              return i.invokeNext();
              }
              }
              
              
              



              I'm not sure if I'm making sense here. I could well be missing the point. :)



              • 4. Re: Delegate implementation
                ovidiu.feodorov

                In that case you need recompilation anyway, because you need to effectively implement that operation on the server delegate. So, if that need arises, you might as well add the method to XServerDelegate interface. You will end having it duplicated on XClientDelegate AND XServerDelegate, which is not worse than what we have today.