Ever inherit a batch of code so disturbing that you just have to rewrite the whole damn thing? Well, I did, and so far... ehh.
The CF powers-that-be tout CFCs as being great because they promote reuse of code. While this is quite true, the overlords of Coldfusion have neglected to mention in any of their documentation just how to go about reusing CFCs well. Sure, you can CFINVOKE methods from it or instantiate it with CreateObject() or access it as a webservice... blah, blah, blah. What I want to know is, why does my CFC cripple the server under high-load?
Yesterday, after spending a month rewriting our shopping cart as a CFC (hey, it's complicated alright?), I was finally able to post it and see what happens. After about an hour, JRun started throwing funny null errors and ran up queued requests like there was no tomorrow. Yikes! I quickly put the old cart back up, and everything was cool again. Okay... so what happened?
I spent most of today investigating. Although CFCs can act like objects, my CFC is stateless. It has no properties of its own and for all intents and purposes is essentially just a nice way to keep my cart code in one place. Every time a method from it is called, it must be passed some identifying variables. I had considered writing it as a state-based CFC and storing unique copies in each user's session scope, but I figured my server couldn't afford to store complex objects in it's memory for up to half an hour at a time. Plus, erasing a user's cart every time their session times out is actually a step down from the old cart code, which uses cookies to store cart info "forever."
So, the methods in my CFC are being accessed by individual CFINVOKE tags, about 4-7 per page. I found a comment on some blog somewhere about how it is better to instantiate the component and then access methods from the instantiated object. Although my CFC is stateless, I thought, hey why not? ... And that turned out even worse. The server lasted about 5 minutes before junking out.
Well... thats all I could come up with for this round. I hate to say it but...
The winner of Round 1 is: Spaghetti code!
Ugh, so what next? I found another random blog that says that you can store stateless CFCS in the application scope. I'm gonna give it a shot tomorrow and see what happens. I'm a little concerned because I saw a forum post by Mr. Camden explaining how CFCs in the application scope became unstable under high-stress. Hmmmm... mind you this post was dated back in 2003 and he was expressing how it may be fixed soon. So... we'll see!
Tuesday, March 18, 2008
CFCs vs. Spaghetti Code: Round 1, Fight!
Posted by
Russ
at
11:25 PM
Labels: cfcs, coldfusion, server management
Subscribe to:
Post Comments (Atom)
2 comments:
Yes, that issue was fixed. It involved queries if I remember right, but it was fixed long, long ago.
Always put "singleton", "stateless" CFCs that you want to reuse in your applications in the Application or Server scope. In CF 7+, you'll just stick them in the onApplicationStart() method to cache them in the Application scope.
see http://www.coldfusionjedi.com/index.cfm/2008/3/24/Ask-a-Jedi-Question-on-Application-based-CFCs
I've implemented this strategy in sites that get tens of millions of requests per month, so yes - it scales very well, whereas instantiating them each with with CreateObject() definitely buckles CF/JRun under high load (I've done many load tests to prove this over the years)
Post a Comment