Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Improving Performance With the Cache Scope in Mule

DZone's Guide to

Improving Performance With the Cache Scope in Mule

Learn about the Mule cache scope and learn how to use it to save time and processing load by caching frequently requested data.

· Performance Zone
Free Resource

Caching is all about application performance optimization, and can be very useful in gaining fast application performance.

Cache scope is one of the scopes in Mule which saves time and processing load by storing and reusing frequently called data in the memory, file system, or database, which saves more processing time and load than if it had to be accessed from the original source location every time. We can put any number of message processors into a cache scope and configure the caching strategy to store the responses (which contain the payload of the response message) produced by the scope’s subflow.

Even though Mule has its default caching strategy, it is recommended to define the global caching strategy because the default strategy uses an InMemoryObject store and should only be used for testing.

Implementation Without Cache

When an end user of a flight booking system is looking for the flight information between Delhi to Kolkata for a particular date, it then goes through the processing of various steps where it connects to multiple vendors to collect the flight details. Finally, after collecting all the details, the response will be returned to the user. The same processing steps will be executed for each incoming request, even if multiple users are looking for the same information, which means if we receive 100 requests for the same source and destination search for a particular date, then all of the processing steps will be done 100 times.

Implementation With Cache

Once the application receives the search request between Delhi and Kolkata for a particular date, the response that has been returned to the user will be stored in a cache, and for all of the next searches for the same source and destination for that particular date, the result can just be returned from the cache without executing the same steps repetitively.

Image title

How It Works

Mule sends a message into the cache scope and the parent flow expects an output. The cache scope processes the message, delivers the output to the parent flow, and saves the output (i.e. caches the response). The next time Mule sends the same kind of message into the cache scope, the cache scope may offer a cached response rather than invoking, again, a potentially time-consuming process.

Each item in the cache is a key/value pair where the key represents the payload at the cache scope entry point. The value is the result at the end of the cache scope. By default, Mule uses SHA256KeyGenerator and a SHA256 digest to generate a key on the payload. For the cache entry value, Mule will cache not just the payload at the end of the cache scope, but the whole MuleEvent. The idea behind all of this is that apart from the payload, you might need other information, such as message properties.

Use Cases:

You can use a cache scope to reduce the processing load on the Mule instance and speed up message processing within a flow. It is particularly effective for

  1. Processing repeated requests for the same information.

  2. Processing requests for information that involve large, non-consumable message payloads.

Configuring an Object Store for Cache

By default, Mule stores all cached responses in an InMemoryObjectStore. Below are the multiple ways of creating a caching strategy and defining a new object store if you want to customize the way Mule stores cached responses.

  • custom-object-store: Custom object stores are useful when you want to use a custom persistence mechanism for your ObjectStore.

  • In-memory: This stores the data inside system memory. The data stored with In-memory is non-persistent, which means in case of an application restart or crash, the cached data will be lost.

  • Managed-store: This stores the data in a place defined by ListableObjectStore. The data stored with Managed-store is persistent, which means in case of an application restart or crash, the cached data will not be lost.

  • Simple-test-file-store: This stores the data in a file. The data stored with the Simple-test-file-store configuration is persistent, which means in case of an application restart or crash, the cached data will not be lost.

Image title

Let’s walk through how to use Cache scope in mule application. In this example flow, "cacheFlow" will be invoked through a REST client. All of the steps, including message processors in the cache scope, will be executed for the first request made for ID= 1 and the response will be returned to the user. The same will be stored in a cache, which will be used to return that response hereafter for all of the subsequent requests made for the same ID without executing the message processor in the cache scope.

Flow:

Image title

Code:

<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:dw="http://www.mulesoft.org/schema/mule/ee/dw"
xmlns:db="http://www.mulesoft.org/schema/mule/db"
xmlns:core="http://www.mulesoft.org/schema/mule/core"
xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:cxf="http://www.mulesoft.org/schema/mule/cxf"
xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core" xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.mulesoft.org/schema/mule/ee/dw http://www.mulesoft.org/schema/mule/ee/dw/current/dw.xsd
http://www.mulesoft.org/schema/mule/db http://www.mulesoft.org/schema/mule/db/current/mule-db.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/cxf http://www.mulesoft.org/schema/mule/cxf/current/mule-cxf.xsd
http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd">


  <ee:object-store-caching-strategy
name="CacheStrategy" doc:name="Caching Strategy" keyGenerationExpression="#[flowVars.id]">  
<in-memory-store name="inMemooryStore" maxEntries="200" entryTTL="20000" expirationInterval="20000"/> 
  </ee:object-store-caching-strategy>
<db:generic-config name="Generic_Database_Configuration"
url="jdbc:hsqldb:hsql://localhost:9001" driverClassName="org.hsqldb.jdbcDriver"
doc:name="Generic Database Configuration" />
<http:listener-config name="HTTP_Listener_Configuration"
host="localhost" port="8081" basePath="/cache" doc:name="HTTP Listener Configuration" />

<flow name="cacheFlow">
<http:listener config-ref="HTTP_Listener_Configuration"
path="/cache" doc:name="HTTP" />
<byte-array-to-string-transformer
doc:name="Byte Array to String" />
        <set-variable variableName="id" value="#[message.inboundProperties.'http.query.params'.id]" doc:name="Variable"/>
        <logger level="INFO" message="#[flowVars.id]" doc:name="Logger"/>
<ee:cache doc:name="Cache" cachingStrategy-ref="CacheStrategy">
<logger level="INFO" message="Before calling the database connector" doc:name="Logger" />
            <db:select config-ref="Generic_Database_Configuration"
doc:name="Save to fgwy_user_role">
<db:dynamic-query><![CDATA[select id,name from employee where id='#[flowVars.id]']]></db:dynamic-query>
</db:select>       
<logger level="INFO" message="After calling the database connector" doc:name="Logger" />
</ee:cache>
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/json
---
payload map ((payload01 , indexOfPayload01) -> {
id: payload01.id,
name: payload01.name
})]]></dw:set-payload>
</dw:transform-message> 
<logger level="INFO" message="#[payload]" doc:name="Logger" />
</flow>
</mule>


Request URL:

http://localhost:8081/cache/cache?id=1

Image title

Hope this helps.

Thanks.

Keep learning.

Topics:
mule ,mule esb ,caching ,scopes ,performance ,performance optimization

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}