7 Replies Latest reply on Aug 5, 2007 4:44 AM by marklittle

    Specific type of ServiceInvoker

    marklittle

      I notice that we now have a:

       public static synchronized void deliverToDeadLetterChannel(Message message) throws RegistryException, MessageDeliverException {
       if (dlQueueInvoker == null) {
       dlQueueInvoker = new ServiceInvoker(INTERNAL_SERVICE_CATEGORY, DEAD_LETTER_SERVICE_NAME);
       }
       dlQueueInvoker.deliverAsync(message);
       }
      


      operation in ServiceInvoker. Although I can understand the necessity for this (make it easier to send specifically to the DLQ), I disagree with the approach. Why not subtype ServiceInvoker and have a specific DLQServiceInvoker? That way we also encourage others to use the SI approach in an extensible and manageable way. Plus, if someone wants to deliver something synchronously to the DLQ we don't have to go back and change the SI interface again.

        • 1. Re: Specific type of ServiceInvoker
          tfennelly

           

          "mark.little@jboss.com" wrote:
          Why not subtype ServiceInvoker and have a specific DLQServiceInvoker?


          Hmmmm... I dunno... I actually intentionally didn't do that because I'd consider that overkill. But more importantly, it would be exploding an API around ServiceInvoker, which I think is a really bad idea. We obviously shouldn't stop people extending SI, but I think we should only introduce multiple SIs into the core API as a very last resort, which this is obviously not.

          If there's a general consensus against having this as a static method on ServiceInvoker, then I'd vote for just getting rid of it altogether and documenting how to do it somewhere (in the SerivceInvoker Javadoc ;-) ). I def wouldn't be voting for creating separate sub classes for doing this type of thing.


          • 2. Re: Specific type of ServiceInvoker
            marklittle

             

            "tfennelly" wrote:
            "mark.little@jboss.com" wrote:
            Why not subtype ServiceInvoker and have a specific DLQServiceInvoker?


            Hmmmm... I dunno... I actually intentionally didn't do that because I'd consider that overkill.


            I think it breaks the abstraction. When we spoke you agreed it was one SI instance per service per client. Now we've got a class specific method that allows you to call the DLQ? Doesn't look right to me. SI is essentially a client stub to a service. Why should there be a specific method on the class to talk to a specific service? If we go that route then we'll be encouraging static methods for transformation, registry, transactions etc. etc.

            If you look at the equivalents to this in CORBA, DCE, DCOM, RMI etc. you'll see what I mean. They have specific instances per service type if needed. Let's go that route and don't pollute the SI space.


            But more importantly, it would be exploding an API around ServiceInvoker, which I think is a really bad idea. We obviously shouldn't stop people extending SI, but I think we should only introduce multiple SIs into the core API as a very last resort, which this is obviously not.


            I don't think you're quite understanding what I mean. I'm not suggesting introducing a new SI. I'm suggesting instroducing a specific instance of a SI class that *only* contacts the DLQ. You can't do anything else with it: all you can do it send messages to the DLQ. I don't see how this is a really bad idea? It's fairly common practice in every distributed system I've had experience with over the past 20+ years. Neither is it an extension to SI. It's a trivial implementation (in pseduo-code):

            class DLQServiceInvoker extends ServiceInvoker
            {
             public DLQServiceInvoker ()
             {
             super(whatever needed to bind the base class to the DLQ);
             }
            }
            


            (Maybe override sendSync if we don't believe that should be used for the DLQ).

            Then stick it in a org.jboss.soa.esb.client.(specific)services package and we're done.

            A heck of a lot better than a static operation on the class IMO and in line with OO principles.


            If there's a general consensus against having this as a static method on ServiceInvoker, then I'd vote for just getting rid of it altogether and documenting how to do it somewhere (in the SerivceInvoker Javadoc ;-) ). I def wouldn't be voting for creating separate sub classes for doing this type of thing.


            • 3. Re: Specific type of ServiceInvoker
              marklittle

              Either dump it or subtype SI. But we definitely shouldn't be leaving that method signature as it currently stands.

              • 4. Re: Specific type of ServiceInvoker
                tfennelly

                I totally got you the first time Mark :-) 20+ years experience or not, creating a separate class (subclass or otherwise) for doing this particular job stinks IMO, sorry ;-)

                Anyway I'm actually all for getting rid of it coz I do agree that it's a broken concept, but not because of anything to do with OO, CORBA, DCE, DCOM RMI etc

                When you think about it, what's the likelihood of only having 1 DLQ in a system. Not sure if we currently support it or not, but I'd imagine that at some stage we'll need to support DLQ config on a per endpoint/Service basis (as well as a system wide default perhaps) and this method would gag on that.

                I do think however that we should try make DLQ delivery as easy as possible and that people shouldn't need to manually "look up" the DLQ in their code and call any special classes. I think we should be able to associate a DLQ with one or more Services/endpoints and have the SI take care of it all from a code perspective e.g. try deliver a message through the SI.... if it fails, SI auto delivers to the service's associated DLQ, OR the calling code can manually do it via the SI instance. Auto doing it would be in line with how the likes of Weblogic does it for JMS (you can configure a DLQ per JMS Destination) and I think it's more in line with the old fire-and-forget line of thinking (otherwise it'd be fire-and-forget-unless-theres-an-error).

                • 5. Re: Specific type of ServiceInvoker
                  marklittle

                   

                  "tfennelly" wrote:
                  I totally got you the first time Mark :-) 20+ years experience or not, creating a separate class (subclass or otherwise) for doing this particular job stinks IMO, sorry ;-)


                  Sorry, but I can guarantee you people will start doing this with services anyway and it's going to happen in JBossESB once we have full contract definition in place. We will have specific stubs for specific services. Experience counts here (just as it does for transformations ;-)


                  Anyway I'm actually all for getting rid of it coz I do agree that it's a broken concept, but not because of anything to do with OO, CORBA, DCE, DCOM RMI etc

                  When you think about it, what's the likelihood of only having 1 DLQ in a system. Not sure if we currently support it or not, but I'd imagine that at some stage we'll need to support DLQ config on a per endpoint/Service basis (as well as a system wide default perhaps) and this method would gag on that.


                  Sure. I hadn't thought we'd be creating specific SI instances (convenience classes) until later down the road anyway.


                  I do think however that we should try make DLQ delivery as easy as possible and that people shouldn't need to manually "look up" the DLQ in their code and call any special classes. I think we should be able to associate a DLQ with one or more Services/endpoints and have the SI take care of it all from a code perspective e.g. try deliver a message through the SI.... if it fails, SI auto delivers to the service's associated DLQ, OR the calling code can manually do it via the SI instance. Auto doing it would be in line with how the likes of Weblogic does it for JMS (you can configure a DLQ per JMS Destination) and I think it's more in line with the old fire-and-forget line of thinking (otherwise it'd be fire-and-forget-unless-theres-an-error).


                  There are different concepts rolled into what you've just said. Fire-and-forget (ignoring errors entirely) is a valid approach and we shouldn't ignore that. Many organisations send messages and don't need responses (even if they are errors) and they'll configure their message sender accordingly. There are a number of reasons for this, but the simplest one is that if the message goes missing then there'll be another one sent in a few seconds/minutes anyway; if there's an error at the processing side then a separate management infrastructure will be monitoring anyway.

                  We should be allowing the DLQ to be used for undelivery of messages in a select way and not over using it. From a synchronous perspective, I think it's fairly clear: if you can't deliver the message then fault back to the sender and let him decide whether or not to then send it to the DLQ. Otherwise what's the point of sync deliver ;-)?

                  If it's async then that's different. Ignoring simplifications, the sender should decide whether or not to use the DLQ by setting the call fields appropriately. If they're not set then no DLQ. If they are set then (assuming the DLQ EPR is used), we go the DLQ route.

                  Going back to what you said about JMS, this says to me we probably want an overloaded sendAsync. sendReliableAsync would send the wrong message (no pun intended!) because it's not reliable delivery at all (unless you're using JMS with transactions as your transport). sendAsyncDLQ?

                  • 6. Re: Specific type of ServiceInvoker
                    marklittle

                    BTW, this is now starting to sound like a different issue than what I started. So let's clear that one up first: for now, let's drop that static method from SI (I think we both agree on that?) Then let's have a separate discussion about how to make DLQ easier. OK?

                    • 7. Re: Specific type of ServiceInvoker
                      marklittle

                       

                      "tfennelly" wrote:
                      I totally got you the first time Mark :-) 20+ years experience or not, creating a separate class (subclass or otherwise) for doing this particular job stinks IMO, sorry ;-)


                      BTW, the other way of doing this (which is essentially the same, but just hides the details), would be to have a SpecificService class (name is open to debate) and have that do:

                      class SpecificService
                      {
                       public static final String DLQ = "DLQServiceName";
                      
                       ServiceInvoker getSpecificService (String name);
                      }
                      


                      So essentially it's a factory that returns SI instances of well defined services that we support. That way there's no overloading of SI and there's also no static method for a specific DLQ service on the SI class definition.