[CB 3.1] Caching Weirdness

The long and short of this is that I have an Interceptor that references a CFC stored in cache. Randomly, the interceptor will lose track of this CFC in cache and I will get an error message that the CFC cannot be found. This happens maybe only a couple of times a day and I’m not sure how to troubleshoot. The other interesting thing about it is that the error tends to be generated after a period of user inactivity (mostly at night). So, that’s the high level problem. The details of what I put together is this:

  • I have an interceptor (‘AuthorizationInterceptor.cfc’) that allows me to secure access to handlers or handler events by adding an additional attribute called permissions at the component level or function level. For example:
  • component permissions=’[“usermanagement”]’
  • function securedAction() permissions=’[“permission1”]’{- My interceptor references another CFC called ‘Authorization.cfc’, its purpose is to read in the handlers metadata, collecting all the permissions info and storing it in its instance scope. Additionally this CFC has a method called ‘HasAuthroization(event,permissions)’ which will allow me to check if the user can access the given event by looking at the data stored in the instance scope.
  • The main interception points used in my interceptor are ‘afterHandlerCreation’ and ‘preEvent’.
  • ‘afterHandlerCreation’ allows me to get the handler after its created and pass it along to the ‘Authorization.cfc’
  • ‘preEvent’ allows me to use the ‘Authorization.cfc’ to see if the user has authorization to the requested event- Some code
    AuthorizationInterceptor.cfc - afterHandlerCreation

`

<---************************************************************************ ---> <---************************************************************************ ---> /* We are storing the permissions metadata in the coldbox cache. We can lookup the permissions settings for a handler or event from here and take the appropriate action */

var ocm = getColdBoxOCM();
var authorization = ‘’;

if(!ocm.lookup(‘AuthorizationManager’)){
var authorization = getModel(‘Authorization’);
ocm.set(‘AuthorizationManager’,authorization);
}else{
var authorization = ocm.get(‘AuthorizationManager’);
}

authorization.addHandler(event,interceptData);
ocm.set(‘AuthorizationManager’,authorization);

return false;

`

AuthorizationInterceptor.cfc - preEvent

`

<---************************************************************************ ---> <---************************************************************************ ---> var authorization = getColdBoxOCM().get('AuthorizationManager'); var handlerExclusion = getProperty('handlerExclusion');

var thisHandler = listDeleteAt(interceptData.processedEvent,listLen(interceptData.processedEvent,"."),".");

if(ArrayFindNoCase(handlerExclusion,thisHandler) eq 0){
var appuser = event.getValue(‘appuser’);
var is_authorized = authorization.HasAuthorization(event.getCurrentEvent(),appuser);

if(!is_authorized){
var handlerAction = event.getValue(‘app_properties’).notAuthorizedHandler;
setNextEvent(event.getValue(‘app_properties’).notAuthorizedHandler);
}
}

return false;

`

The line above highlighted in red is what is generating the error. The message is ‘Variable AUTHORIZATION is undefined.’.

I suspect at some point the cache is being cleared after a period of time and during the preEvent the ‘AuthorizationManager’ key is not in the cache anymore. I’m also thinking that the handlers and cachebox are not on the same cache clearing scheduling.

Can anyone help?

Thanks.
Brett

You should almost always check if something exists in the cache. Memory usage or number of items in a cache could have caused the object to be evicted, or your timeout could have been reached, so there is no guarantee it will be in the cache. So, I would wrap your get in a lookup check or check if its null and then set it back in the cache if its not there.

Hope that helps,
Curt

Hi Curt,

I’m going to stew on that one for a bit and figure out how to handle. The Authorization object contains instance data that is populated during the afterHandlerCreation event, so just re-initing it if its not in the cache during the preEvent phase won’t be enough. In order to do so I will need to re-run whatever code I used in the ‘afterHandlerCreation’ in order to have the instance data available.

I’ll post an update after I have it working.

Thanks.
Bret

How is the CFC set in the cache? If it is set with a timeout of 0 (eternal) it will not be evicted or garbage collected.

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Hi Brad,

In my code above I’m currently doing this (where ocm is a call to the getColdboxOCM() in the inerceptor):

`
ocm.set(‘AuthorizationManager’,authorization);

`

If I do the following, does this accomplish what you are talking about?:

`
ocm.set(‘AuthorizationManager’,authorization,0);

`

Thanks,
Brett

Yes. I think that otherwise the default timeout of the cache provider is used. Hit your site with ?debugmode=1&debugpanel=cache and find that item in the cache. it will tell you the timeout that it is using.

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Hi Brad,

I added the line:

`
ocm.set(‘AuthorizationManager’,authorization,0);

`

I checked the cachebox panel and the timeout for the ‘authorizationmanager’ is set to 120. I see that my handlers are set to 0. I tried doing a framework reinit and restarted CF and my timeout on authorizationmanager is still 120.

I’ll be looking through some debug logs to see if I can figure out what is going on, but wanted to give you a heads up.

Thanks.

Brett

What cache provider are you using?

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Hi Brad,

Its the default provider.

Brett

.

Hi Brad,

Just an updated on this. After banging my head as to why I couldn’t get the AuthorizationManager to register into cache with a timeout of 0, I stated doing some logging. The logging seemed to indicate that there was some implicit registering of the AuthorizationManager happening prior to the code I had listed above. I believe this had something to do with the AuthorizationManager being mapped in Wirebox, though this is just a guess. I wound up re-factoring my Interceptor so that AuthorizationManager was put into cache with a 0 timeout during the ‘afterAspectsLoad’ event. My afterHandlerCreation and preEvent events just make the assumption that AuthorizationManager is already there, which I know isn’t a great assumption, but so far so good. AuthorizationManager is a appearing in cachebox with a timeout of 0 and I haven’t received the error message anymore.

Thanks everyone for their input.
Brett