cancel
Showing results for 
Search instead for 
Did you mean: 

Share sitedata remote persister cache

jpotts
World-Class Innovator
World-Class Innovator
I need to be able to set any user's dashboard using a web script invoked from curl. I've looked at the web script that the customize dashboard dialog posts to. My first approach was to post similar JSON to that script. Unfortunately, although you don't get an error, through the debugger I can see that the remote store is rejecting the persister's associatePage, unbind, and bind component calls with a 404 not authorized. I tried calling the Share tier web script with user/password in the header and by using a ticket instead, but nothing helped. I even tried setting the web script to do a runas admin but I'm not sure that is supported in the Share tier. I basically gave up on this approach having decided that I do not understand what's going on from an authentication perspective on the Share web script tier.

So, I decided to use a second approach which is to simply create the same XML in the AVM store on the repo tier that the persister would have. This actually works great. I can call my repo tier web script with JSON similar to what was being posted on the Share tier, and my web script creates the dashboard.xml and component XML files in the AVM sitestore.

The issue is that there is a cache on the Share tier that is holding on to the data objects. The persister classes have a method called invalidateCache, so my attempt to fix this was to create a Surf tier web script that calls the invalidateCache method. (Luckily, this doesn't require any authentication). This does seem to clear the cached components but it is not clearing the cached template instance reference.

In other words:
0. Start with a user with a two column dashboard, two dashlets in each column.
1. Run repo tier web script to create page and component XML, switching the two column layout to a one column layout and eliminating all but one component.
2. Log in to Share.
3. Old dashboard is still visible (as expected) because the surf tier cache still has the old data objects.
4. Run share tier web script to clear the cache.
5. Log out of and back into Share.
6. The dashboard now shows the correct components (just the one we reduced to) but still the two column layout (an empty second column is showing).
7. Restart Share tomcat. Log in. Now that the memory is cleared, the dashboard is correctly showing the one dashlet in the one column layout.

So, it appears to be holding on to the dashboard.xml page data object which is where the template instance is specified.

My "clear cache" web script in the Share tier is simple:
<bean id="webscript.com.obscured.admin.clearCache.get" parent="webscript" class="com.obscured.share.admin.ClearCacheGet">
       <property name="persisters">
           <list>
               <ref bean="webframework.objects.persister" />
           </list>
       </property>
   </bean>

And the webscript:

public class ClearCacheGet extends DeclarativeWebScript {

   // Dependencies
   private List<ModelObjectPersister> persisters;

   @Override
   protected Map<String, Object> executeImpl(WebScriptRequest req, Status status, Cache cache) {
        Map<String, Object> model = new HashMap<String, Object>();

        for (ModelObjectPersister persister : persisters) {
           if (persister instanceof CachedPersister) {
                ((CachedPersister)persister).invalidateCache();
            }
        }

        return model;
   }

   public void setPersisters(List<ModelObjectPersister> persisters) {
      this.persisters = persisters;
   }
   
}

Incidentally, if I run the process again, but this time, switch from a one column layout with one dashlet to a two column layout with four total dashlets, after the cache is cleared I can log in and see that the layout is still one column, but contains the correct components for that column. Restarting tomcat resolves the issue and shows the expected two-by-two dashboard.

Maybe the page object is being cached somewhere that my cache clearing web script doesn't touch?

Jeff

PS. This is 3.4a community.
4 REPLIES 4

jpotts
World-Class Innovator
World-Class Innovator
One of the Alfresco Engineers told me at DevCon he thought this may have been fixed (and it could be in head) but I just confirmed this problem exists on both 3.4a and 3.4b Community. Watch the Jira ticket if you are interested: http://issues.alfresco.com/jira/browse/ALF-5967

kevinr
Star Contributor
Star Contributor
I have reproduced the issue. Diagnosis: SpringMVC has it's own cache of "views" against our view resolvers - we also need to clear the springmvc view resolver caches when we clear the surf/webscript caches.

i.e. you could probably do this from your webscript as a work-around for now:

AbstractCachingViewResolver.clearCache(); is the method to use

Kev

kevinr
Star Contributor
Star Contributor
OK so the complete code you want for your reset webscript is:


            // we must reset the SpringMVC view resolvers - as they maintain a reference to View
            // object which could themselves reference pages or templates by ID
            Map<String, ViewResolver> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(
                    applicationContext, ViewResolver.class, true, false);
            for (ViewResolver resolver : matchingBeans.values())
            {
                if (resolver instanceof AbstractCachingViewResolver)
                {
                    ((AbstractCachingViewResolver)resolver).clearCache();
                }
            }
You'll need to Spring in the applicationContext reference via the ApplicationContextAware interface or similar.

I have added this to the Surf command console (/share/page/console) and it will now reset the SpringMVC View Resolvers when the Refresh Object Registry cmd is used.

Kev

Kev

berenicestr69
Champ in-the-making
Champ in-the-making
Hello Kevin, I need the steps fo do this.

I put this code on my head of my WebScript

// we must reset the SpringMVC view resolvers - as they maintain a reference to View
// object which could themselves reference pages or templates by ID
Map<String, ViewResolver> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(
      applicationContext, ViewResolver.class, true, false);
for (ViewResolver resolver : matchingBeans.values())
{
   if (resolver instanceof AbstractCachingViewResolver)
   {
      ((AbstractCachingViewResolver)resolver).clearCache();
   }
}

But this send me error. Must I have any include for this???
Must i haveinclude something on my description XML of my web script???

I haven´t have SHARE, only I have alfresco, yu said:
I have added this to the Surf command console (/share/page/console) and it will now reset the SpringMVC View Resolvers when the Refresh Object Registry cmd is used.

How in alfresco , not Share, reset SpringMVC ???

This code that the other people comment,is it necesary?? must I include?? if I must include, What file???

The code:
<bean id="webscript.com.obscured.admin.clearCache.get" parent="webscript" class="com.obscured.share.admin.ClearCacheGet">
       <property name="persisters">
           <list>
               <ref bean="webframework.objects.persister" />
           </list>
       </property>
   </bean>