7

We are using DD4T 2.0 in our MVC application with Tridion 2013 SP1 as CMS. Since DD4T 2.0 does not support RMI based cache invalidation, we setup JMS based cache invalidation with ApacheMQ. The invalidation is working and I am getting both cache set and invalidation message in logs, but when I set the attribute to set DD4T cache (dd4t.caching.page, dd4t.caching.component) the cache is not getting invalidated before 1 hour i.e. dd4t cache is not getting invalidated. We have also added DD4T.Caching.ApacheMQ package to our application with below setting

<!-- DD4T ApacheMQ configuration -->
        <add key="DD4T.JMS.Hostname" value="localhost" />
        <add key="DD4T.JMS.Port" value="61616" />
        <add key="DD4T.JMS.Topic" value="TridionCCS" />
        <!-- END DD4T ApacheMQ configuration -->

The cache is still not getting invalidated. Apart from above three settings, is there any configuration setting which I am missing?

  • When you say "does no support RMI" does that mean it doesn't support the Cache Channel Service? – Neil Mar 24 '17 at 7:14
  • @Neil- Tridion object cache get invalidated using RMI but the cache which DD4T 2.0 builds on top of object cache doesnot get invalidated. In DD4T 1.3, there was a mechanism where it keeps on polling broker for an update to invalidate its cache. – rdhaundiyal Mar 24 '17 at 7:30
  • Yeah - so that polling mechanism is still there in DD4T 2.0 right? – Neil Mar 24 '17 at 7:32
  • AFAIK, it is not there in 2.0 and that i asked in one of the question on this forum – rdhaundiyal Mar 24 '17 at 9:11
4

Please note: updated answer!

The JMS-based cache invalidation of the .NET version of DD4T in a pre-release, so you have to do a bit of work.

This is what you should do:

  • Add a NuGet reference to DD4T.Caching.ApacheMQ (set it to prerelease mode since there is no official release yet)

  • Add the following line to the Application_Start method, before you call builder.UseDD4T()

    builder.RegisterType<JMSMessageProvider>().As<IMessageProvider>();
    
  • When you have set the DD4T references using builder.UseDD4T(), you need to start the message provider and subscribe your CacheAgent to it, like this:

    var cacheAgent = diContainer.Resolve<ICacheAgent>();
    if (cacheAgent is DefaultCacheAgent)
    {
        messageProvider.Start();
        ((DefaultCacheAgent)cacheAgent).Subscribe(messageProvider);
    }
    

The message provider will now listen to the configured address (using the DD4T.JMS.xxx settings that you have already) for invalidation messages which are broadcast by the deployer.

But there is also a change you need to do on the deployer end. The DD4T framework contains a little-used customization of the Tridion CacheChannel logic. To implement, do this:

  • Download this source code and build it using some Java IDE: https://github.com/dd4t/dd4t-cachechannel

  • Create a jar file from it

  • Copy the jar file to the lib folder of the deployer

  • In the cd_storage_conf.xml of the deployer, locate the Connector element inside the RemoteSynchronization section.

  • Change it so it uses the bespoke connector, like this

<Connector Class="com.tridion.cache.TextJMSCacheChannelConnector" Topic="Tridion" Strategy="AsyncJMS11">

  • Restart the deployer

It should now broadcast text messages instead of binary messages. This is needed because the binary messages cannot be consumed through .NET.

As I said, it won't be easy. If you manage it, please blog. It will make it easier for the rest :)

  • yes, i did provided the topic, forgot to mention it in the question above. But apart from these how does the web application i.e. dd4t framework knows how to invalidate the cache. in dd4t 1.3 there was a callback interval which keeps on waiting but that is not the case in dd4t2.0 – rdhaundiyal Jan 21 '17 at 12:14
  • Thanks Quirijin, I will give it a try but by any chance is it possible to use the old call back interval with DD4T 2.0 – rdhaundiyal Jan 22 '17 at 9:01
  • I did some more digging, it is not as bad as I thought. Still it's an experimental feature, which is not yet formally released. See updated answer! – Quirijn Jan 22 '17 at 17:07
  • Hi Quirijn, does the topic given in connector string should be the same which is provided in RemoteSynchronization "topic.Tridion" property – rdhaundiyal Jan 26 '17 at 13:29
  • Thanks Quirijin, I was able to invalidate dd4t cache using approach provided by you. The only change was that we do not need to add the line to add dependency of messageprovider in code. The nuget package dll itself create a singleton instance of jmsmessageprovider via dependencymapping class. If we add the dependency ourselve in the code, we need to make it singleton scope. – rdhaundiyal Jan 28 '17 at 18:03
1

Summarizing the solution mentioned in answer above

Config

 <RemoteSynchronization>
                    <Connector Class="org.dd4t.cache.TextJMSCacheChannelConnector" Topic="Tridion" Strategy="AsyncJMS11"> 
                    <JndiContext>
                    <Property Name="java.naming.factory.initial" Value="org.apache.activemq.jndi.ActiveMQInitialContextFactory"/>
                    <Property Name="java.naming.provider.url" Value="tcp://localhost:61616?soTimeout=5000"/>
                    <Property Name="topic.Tridion" Value="TridionCCS"/>
                    <!--Property Name="objectMessageSerializationDefered" Value="true"/-->
                    </JndiContext>
                    </Connector>
    </RemoteSynchronization>

Code after builder.UseDD4T

JMSMessageProvider messageProvider = container.Resolve<IMessageProvider>() as JMSMessageProvider;
            var cacheAgent = container.Resolve<ICacheAgent>();
            var defaultCacheAgent = cacheAgent as DefaultCacheAgent;
            if (defaultCacheAgent != null)
            {
                messageProvider.Start();
                defaultCacheAgent.Subscribe(messageProvider);
            }

While using ApacheMQ use version less than v12 and v13 as there is some issue to deserialize the version above 11.0. I raised a question here but it is more related to java.

The jar file provided in the git hub publish event as text messages instead of object messages so that .net subscriber can read it. You need to modify the jar file so that while receiving the event at the receiver side the textmessages should invalidate the Tridion object cache as well which it will not do without modification to the connector. Need to override the Validate() method in jmscachechannelconnector class along with setlistener. Code listing is available here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.