ColdFusion array functions don't appear to be thread safe
Tags: General, Coldfusion, ColdFusion 9, Coldbox
I have been looking into a problem that I have just started noticing, and when I looked into it further I was shocked to find that under a good load on the website I was starting to get the following error.
java.util.ConcurrentModificationException at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372) at java.util.AbstractList$Itr.next(AbstractList.java:343)
And is related to this post I made a few days ago.
The question that I have is what or how is this actually happening.
And I don't have an answer for this in anyway, but what I can tell you is that if I remove the ArrayDelete function then the error does not happen. So how did I come across this problem, to answer that I need to point you to the above link. In this link I am creating an array of items that later I can remove, and this is when I noticed that during a bit of a load I started getting some errors.
Now the first time I got this I wasn't sure if it was something that I was doing, or maybe a fault in ColdBox. But what I discovered has left me speechless in this situation.
So lets look at the following code.
for(var key in instance.interceptors) {
controller.getInterceptorService().unRegister(interceptorName=key);
}
}
What I forget to do here was that after deregistering the interceptor, I forgot to remove the item from the array. This began to cause a problem because the array size grew so fast and quick it just ended up crashing the application, so I went about this the way that most people would. Which was to modify the code to do this.
for(var key in instance.interceptors) {
controller.getInterceptorService().unRegister(interceptorName=key);
arrayDelete(instance.interceptors, key);
}
}
The very first thing that happened was that the application crashed with the same error message, so I thought that this has to be a race condition and the best thing to do is lock this. So to make sure everything was covered I decided to not only lock this bit of code, but I would also lock the code that was appending to the array as well.
And just to make sure, killed the ColdFusion server and rebooted the service.
And I got the error message the very first time the Application ran, at this point I was stumped. I thought that maybe I was using the arrayDelete wrong, and the more I played with this the more I realised that this is not a normal error that I can fix.
Ok so lets try something else, I now wrapped this in a try/catch block to lock it down some more. And I also changed the code to look like this.
lock scope="request" type="exclusive" timeout="10" {
// Unregister any interceptors that have been registered
for(key in instance.interceptors) {
var position = arrayFind(instance.interceptors, key);
}
// Remove the Services directory for Modules
beanFactory.removeExternalLocations(modules[interceptData.modulename].invocationPath & '.services');
}
} catch(Any e) {
writeDump(e);
writeDump(instance);
abort;
}
What I found was that I was still getting this error, and I removed the arrayFind and stopped and restarted ColdFusion and no longer got the error. Put this line back in and sure enough the error message happens again.
I am at a real loss here as to why or how this is occurring, but the one thing that I can say is that the array functions in ColdFusion can't be thread safe. It is the only likely conclusion here.
-
If anyone is interested this has been resolved, the error message was not what I thought it would be. The solution to fix this was that one needs to break out of the loop when doing a delete from the array, and another way would be to loop backwards through the array.
# Posted By Andrew Scott | 4/23/11 6:36 PM



TweetBacks