• Subscription Options

  • What I write about

  • RSS Latest News From MuleSoft

  • Archives

  • Technical Features

  • Visitors Online

  • Archive for 2009

    Short Circuiting The Response Flow

    Monday, December 14th, 2009

    Today’s guest post is from Stephen Fenech, Consultant at Ricston who talks about his most recent Mule engagement.

    A couple of weeks ago I was at SwissCom, the ‘leading Swiss provider of innovative communications and IT solutions’. They are currently using Mule in one of their major projects and we came across an interesting scenario. For this post I have watered down the scenario slightly; to not distract you from the main details while still leaving in all the relevant items.

    We had a synchronous request from an external client, which was forwarded in parallel to multiple services. The results from these services were aggregated and then sent back as the response to the client.

    <service name="MyService">
    	<inbound>
    		<inbound-endpoint ref="InboundEndpoint" 
    			synchronous="true" />
    	</inbound>
    	<component  class="my.Component" />
    	<outbound>
    		<multicasting-router>
    			<outbound-endpoint ref="Out1">
    			<outbound-endpoint ref="Out2">
    			<reply-to ref="Reply" />
    			<payload-type-filter 
    				expectedType="my.Request"/>
    		</multicasting-router>
    	</outbound>
    	<async-reply>
    		<inbound-endpoint ref="Reply" />
    		<custom-async-reply-router class="my.Aggregator"/>
    	</async-reply>
    <service>

    This is quite a common pattern, however since the requests to obtain this information (the ones to Service1 and Service2) were quite heavy, the results were being cached. The Main service would check if there is a cached result and, if so, will return this result. The way this was solved was to have two routers with filters. If the MainService produces a request, the normal flow will be used but if a result is found in the cache then this will be sent directly to the Asynchronous Reply Aggregator.

    <service name="MyService">
    	<inbound>
    		<inbound-endpoint ref="InboundEndpoint" 
    			synchronous="true" />
    	</inbound>
    	<component  class="my.Component" />
    	<outbound>
    		<multicasting-router>
    			<outbound-endpoint ref="Out1">
    			<outbound-endpoint ref="Out2">
    			<reply-to ref="Reply" />
    			<payload-type-filter 
    				expectedType="my.Request"/>
    		</multicasting-router>
    		<multicasting-router>
    			<outbound-endpoint ref="Reply">
    			<payload-type-filter 
    				expectedType="my.Result"/>
    		</multicasting-router>
    	</outbound>
    	<async-reply>
    		<inbound-endpoint ref="Reply" />
    		<custom-async-reply-router class="my.Aggregator"/>
    	</async-reply>
    <service>

    This worked, however, it was slightly inefficient since we use an extra thread to dispatch the message over VM, only to be aggregated by the original thread. We wanted to push Mule to the limit so even minor improvements would make the server handle a larger load.

    So, we asked ourselves, what if we could short circuit the flow so that a cached result is sent directly to the client without passing this result over VM and then blocking & waiting for the same result. How can we do this short-circuiting in the most painless way possible?

    The secret is in the getResponse method of the aggregator. By default we simply use the method of the parent, which makes use of the response aggregator to block waiting for the responses after which the custom aggregation is called and this method will return the aggregated message. In our case, we want to return the response immediately in certain situation. The getResponse method gets a Mule Message as a parameter. Typically, this message is the one sent out by the outbound router and is used in order to get the info to correlate on. In the case where no outbound router accepts the message returned by the service component this message is passed on to the getResponse method. So all we have to do is filter the cached message on the outbound side so that nothing is sent out. Then in the getResponse method, when we return the cached message or call the normal parent method.

    In order to make things a bit more generic, a filter was used to decide if the message is a response or not, making the router configurable. Another advantage of this is that by looking at the configuration, you can tell that there is something different about this aggregation router thus making the config more explicit.

    public class CustomAggregator extends ResponseCorrelationAggregator {
     
    	// This filter is used to check if the result should be sent 
    	// back immediately rather than wait for the aggregation.
    	private Filter shortCircuitingFilter;
     
        @Override
        public MuleMessage getResponse(MuleMessage message) throws
    		RoutingException
        {
         if(shortCircuitingFilter!=null&&shortCircuitingFilter.
    		accept(message))
            {
            	logger.debug("Short-Circuiting flow.");
            	return message;
            }else
            {
            	return super.getResponse(message);
            }
        }

    The configuration is as follows:

    <service name="MyService">
    	<inbound>
    		<inbound-endpoint ref="InboundEndpoint" 
    			synchronous="true" />
    	</inbound>
    	<component  class="my.Component" />
    	<outbound>
    		<multicasting-router>
    			<outbound-endpoint ref="Out1">
    			<outbound-endpoint ref="Out2">
    			<outbound-endpoint ref="Out3">
    			<reply-to ref="Reply" />
    			<payload-type-filter 
    				expectedType="my.Request"/>
    		</multicasting-router>
    	</outbound>
    	<async-reply>
    		<inbound-endpoint ref="Reply" />
    		<custom-async-reply-router class="my.Aggregator">
    			<spring:property name="shortCircuitingFilter" 
    				ref="ShortCircuitingFilter"/>
    		</custom-async-reply-router>
    	</async-reply>
    <service>

    With this simple 10 line tweak we managed to improve the flow, reducing the complexity of the scenario and making the configuration more elegant.

    If you enjoyed this post, make sure you subscribe to my RSS feed!

    Joining The Dots

    Thursday, December 3rd, 2009

    I have a component that is being hosted as a service in Mule and I want to set one of its properties from within config. Specifically, I want to be able to set the value of this property to another class.
    (more…)

    If you enjoyed this post, make sure you subscribe to my RSS feed!

    Entry-Point Resolution using Interfaces

    Monday, November 30th, 2009

    Last week, I blogged about an unusual error I encountered while coding and mentioned that I was not sure why this happened. I’ve since solved the problem and present the explanation to you here.
    (more…)

    If you enjoyed this post, make sure you subscribe to my RSS feed!

    NoSatisfiableMethodsException and Component Bindings

    Thursday, November 26th, 2009

    I was working with Component Bindings this week and ran into an unusual error. I had a simple class that had a single method which accepts a String parameter. I had a test case that I was building around the class and around its use within a service in Mule. All worked well. Then I tried to add the element to the component like so:
    (more…)

    If you enjoyed this post, make sure you subscribe to my RSS feed!

    Changing Log4j Settings Dynamically

    Monday, November 23rd, 2009

    I was working together with the good people at the Control Group recently and had a requirement to be able to selectively change the log4j setting in Mule. Specifically, they wanted to be able to have a running instance of Mule suddenly switch from, say, ERROR to DEBUG while they diagnose some problem with a message flow and then turn the log4j setting back to ERROR.
    (more…)

    If you enjoyed this post, make sure you subscribe to my RSS feed!

    Processing only one copy of a message

    Thursday, November 19th, 2009

    In integration, there often are situations when the same message is delivered more than once. Perhaps someone hit a re-send button, perhaps there was a failure in communication and all the messages were re-sent (even the ones that originally made it through) or perhaps some process decided to keep sending the same message.  Whatever caused it, there are instances when processing this message multiple times could be dangerous. Think of a credit card payment, for instance.  This post examines how to avoid this situation in Mule.

    (more…)

    If you enjoyed this post, make sure you subscribe to my RSS feed!

    Choosing the Best Mule ESB Entry-Point Resolver

    Monday, November 16th, 2009

    I’ve written a number of blog posts in recent weeks about Mule’s flexible entry-point resolver (EPR) mechanism but while the posts have shed light on how the various options work, I haven’t commented on when to best use different EPRs. This post puts this straight.
    (more…)

    If you enjoyed this post, make sure you subscribe to my RSS feed!

    Entry Point Resolver Sets

    Thursday, November 12th, 2009

    One interesting feature that I have rarely used in Mule 2 is the ability to have multiple entry point resolvers (EPRs) configured in a single model. This was unavailable in Mule 1 and is a rather neat way of combining multiple EPRs inside a single model rather than split your configuration into multiple models.
    (more…)

    If you enjoyed this post, make sure you subscribe to my RSS feed!

    An Array By Any Other Name

    Thursday, November 5th, 2009

    With all the recent posts about entry point resolvers, I’ve shown how you can invoke a method based upon a number of techniques like using the method name but in each case, my examples had methods that contained one single input parameter. What if my methods have multiple arguments?
    (more…)

    If you enjoyed this post, make sure you subscribe to my RSS feed!

    The Self-Conscious (Mule) Service

    Monday, November 2nd, 2009

    In the good old days of Mule 1.x, any component that wanted to be aware of its configured state could implement the UMODescriptor interface and get whatever information was needed. This interface is no longer available in Mule 2 but there is a org.mule.api.service.ServiceAware interface that can provide the same sort of information.
    (more…)

    If you enjoyed this post, make sure you subscribe to my RSS feed!

    © Copyright 2005-2008 Ricston, All Rights Reserved
     Sitemap   Privacy Policy    Legal