Re: How Many CFCs is too many CFCs
Andrew, Can you elaborate on the problems you've seen loading Application scoped objects into the request scope? We're having some problem with this as well, re: garbage-collection. Is there any documentation you can point me at for this issue? What alternative do you recommend? Just always calling the shared-scope object directly, instead of referencing the request scoped object? For what it's worth, the request scoped object would just be a pointer to the App-scoped object. So on request end, the pointer should be set null, and should be garbage-collectable, right? Cheers, Kris On Tue, Jul 13, 2010 at 3:22 PM, Andrew Clarke s...@clarke.ca wrote: I took a quick read through your email and couldn't find anything inherently wrong with the design IMHO. Having 60 objects in the application scope I presume is analogous to saying you have 60 singletons. Let's say you have 10 simultaneous requests at any given point. It's better to have 60 object instances than 600 which is what you'd get if you put them in the request scope or somewhere else. I also don't see any real issue to having 60 lightweight objects vs. 20 where each one is 3x as large. They aren't going to multiply as the server loads up. Using application-scoped objects means that you will need to be very sure you are scoping all your variables correctly to avoid bugs. Also, be sure you're not adding persistent objects like session or application objects into any other objects like your request object. I've had JVM GC issues when I've done that as it seems that the request objects aren't garbage-collected properly as they contain objects in the session or application scope. Make sure your variables are scoped properly, make sure you're not mixing your persistent and non-persistent scopes together (like copying application.foo into request.bar.foo) and you should be fine. - Andrew. ~| Order the Adobe Coldfusion Anthology now! http://www.amazon.com/Adobe-Coldfusion-Anthology-Michael-Dinowitz/dp/1430272155/?tag=houseoffusion Archive: http://www.houseoffusion.com/groups/cf-talk/message.cfm/messageid:335344 Subscription: http://www.houseoffusion.com/groups/cf-talk/subscribe.cfm Unsubscribe: http://www.houseoffusion.com/groups/cf-talk/unsubscribe.cfm
Re: How Many CFCs is too many CFCs
I don't recall 100% what the problem was, but I'll tell you what I remember. I built www.knappfast.com a few years ago using ColdBox ColdSpring. If you look at the site, bear in mind that I have nothing to do with the look feel, and that it was started in 2007 ;-) For various reasons, it just went live last month. Anyway, there were some singleton objects, and some other objects. There were some instances where I tried to put a singleton into other objects. For example, I'd have, say, a cart. Each user would have his/her own cart, but there would only need to be one cart DAO. So I put the cart DAO in as cart.DAO so I could do something like cart.DAO.save(). I'm simplifying things a bit but you get the idea. CartDAO was probably saved as a singleton in ColdSpring. I also have some very large objects that can store a LOT of data. There are some processes that pull tens of thousands of products, so if a bunch of those aren't released, you'll see memory climb very rapidly and then not get released. The issue was that if CartDAO was saved in the application or session scope, the cart object wouldn't GC properly as it had a handle on an application-scoped object. I tried a few things, including: 1. Changing JVM arguments to allow a larger max memory size (-XX:MaxPermSize=768m). While this certainly helped, it really only helped to delay the problem rather than to eliminate it. 2. Using structCopy(). However, structCopy() only copies the topmost part of a structure (or object) by value and copies everything else by reference. Therefore this didn't resolve the problem. 3. Using duplicate(). IIRC this helped in development on CF9 but when I went to deploy on CF7 I found out that you can't use duplicate() on objects, only generic structures. 4. Ripping out ColdBox and ColdSpring. I wrote my own very lightweight replacement framework that only does the things I need it to do. This helped a lot as I now have fewer black boxes in my code, and things run a lot faster and consume less memory. 5. I also tried explicitly calling garbage collection at the end of every request: var obj = createObject(java,java.lang.System); obj.gc(); obj.runFinalization(); This certainly adds a bit of overhead to every page request and I wouldn't recommend this specific approach to a high-volume site, but it tends to bring down memory usage more quickly than waiting for Java to GC. However, it doesn't resolve the core problem if garbage collection isn't releasing the memory anyway. 6. Finally, I ended up realizing what the problem was and stopped using session and application singletons. I now create a per-request singleton object that gets destroyed along with the rest of the request. It's not a high-volume site and this was a better solution than re-architecting everything to allow session or application-based singletons. I'm sure there are others on here who have done a better job of avoiding, identifying, and/or resolving this issue, but these are the steps I went through. - Andrew. On 2010-07-14, at 06:42, Kris Jones wrote: Andrew, Can you elaborate on the problems you've seen loading Application scoped objects into the request scope? We're having some problem with this as well, re: garbage-collection. Is there any documentation you can point me at for this issue? What alternative do you recommend? Just always calling the shared-scope object directly, instead of referencing the request scoped object? For what it's worth, the request scoped object would just be a pointer to the App-scoped object. So on request end, the pointer should be set null, and should be garbage-collectable, right? Cheers, Kris ~| Order the Adobe Coldfusion Anthology now! http://www.amazon.com/Adobe-Coldfusion-Anthology-Michael-Dinowitz/dp/1430272155/?tag=houseoffusion Archive: http://www.houseoffusion.com/groups/cf-talk/message.cfm/messageid:335367 Subscription: http://www.houseoffusion.com/groups/cf-talk/subscribe.cfm Unsubscribe: http://www.houseoffusion.com/groups/cf-talk/unsubscribe.cfm
Re: How Many CFCs is too many CFCs
One reason I ask is that I've done quite a bit of work on trying to resolve this exact issue in an application we're working now. I did find a couple of relevant posts, that appear to address the issue. We're still having some problems with other code, but fixing the missing output attribute problem seemed to resolve a good deal of the problems we were having. http://www.bytestopshere.com/post.cfm/must-read-coldspring-bug-memory-leak http://blog.maestropublishing.com/fixing-a-mysterious-memory-leak-on-coldfusion We also ran through with varscoper, and found one place in particular where a non-var scoped variable was hurting us big time. But I think pointing to a var scoping issue as a memory leak would be a rare occasion -- more likely just a big problem with incorrect data. I'm really curious what other folks have experienced as regards the hard-bind issue. I know many are using frameworks that would experience this issue, so I can't imagine it has gone unnoticed. Cheers, Kris On Wed, Jul 14, 2010 at 10:52 AM, Andrew Clarke s...@clarke.ca wrote: I don't recall 100% what the problem was, but I'll tell you what I remember. I built www.knappfast.com a few years ago using ColdBox ColdSpring. If you look at the site, bear in mind that I have nothing to do with the look feel, and that it was started in 2007 ;-) For various reasons, it just went live last month. Anyway, there were some singleton objects, and some other objects. There were some instances where I tried to put a singleton into other objects. For example, I'd have, say, a cart. Each user would have his/her own cart, but there would only need to be one cart DAO. So I put the cart DAO in as cart.DAO so I could do something like cart.DAO.save(). I'm simplifying things a bit but you get the idea. CartDAO was probably saved as a singleton in ColdSpring. I also have some very large objects that can store a LOT of data. There are some processes that pull tens of thousands of products, so if a bunch of those aren't released, you'll see memory climb very rapidly and then not get released. The issue was that if CartDAO was saved in the application or session scope, the cart object wouldn't GC properly as it had a handle on an application-scoped object. I tried a few things, including: 1. Changing JVM arguments to allow a larger max memory size (-XX:MaxPermSize=768m). While this certainly helped, it really only helped to delay the problem rather than to eliminate it. 2. Using structCopy(). However, structCopy() only copies the topmost part of a structure (or object) by value and copies everything else by reference. Therefore this didn't resolve the problem. 3. Using duplicate(). IIRC this helped in development on CF9 but when I went to deploy on CF7 I found out that you can't use duplicate() on objects, only generic structures. 4. Ripping out ColdBox and ColdSpring. I wrote my own very lightweight replacement framework that only does the things I need it to do. This helped a lot as I now have fewer black boxes in my code, and things run a lot faster and consume less memory. 5. I also tried explicitly calling garbage collection at the end of every request: var obj = createObject(java,java.lang.System); obj.gc(); obj.runFinalization(); This certainly adds a bit of overhead to every page request and I wouldn't recommend this specific approach to a high-volume site, but it tends to bring down memory usage more quickly than waiting for Java to GC. However, it doesn't resolve the core problem if garbage collection isn't releasing the memory anyway. 6. Finally, I ended up realizing what the problem was and stopped using session and application singletons. I now create a per-request singleton object that gets destroyed along with the rest of the request. It's not a high-volume site and this was a better solution than re-architecting everything to allow session or application-based singletons. I'm sure there are others on here who have done a better job of avoiding, identifying, and/or resolving this issue, but these are the steps I went through. - Andrew. On 2010-07-14, at 06:42, Kris Jones wrote: Andrew, Can you elaborate on the problems you've seen loading Application scoped objects into the request scope? We're having some problem with this as well, re: garbage-collection. Is there any documentation you can point me at for this issue? What alternative do you recommend? Just always calling the shared-scope object directly, instead of referencing the request scoped object? For what it's worth, the request scoped object would just be a pointer to the App-scoped object. So on request end, the pointer should be set null, and should be garbage-collectable, right? Cheers, Kris ~| Order the Adobe Coldfusion Anthology now!
How Many CFCs is too many CFCs
Hi folks, I need to ask what you more experienced folks thing about my application design. I have some reservations about the number of CFC's loaded into the application scope and the number of calls to CFC methods per request. Background: -Client variable DB storage -Not able to use session vars -2 web servers -60+ CFC's loaded into the application scope -Application is for form design software (like a simplified web based Adobe Designer sort of thing..) On the front end (ExtJS) the client builds a form by adding textfields, selects, radios etc. This creates a JSON packet on the server side that describes the form model. Example: { Formname:'myform', Id:'123', isSecure:true, children:[ { class:'TextField', name:'First Name', id:'123' } , { Class:'Select', Name:'Province', Options:['BC','AL'] } ] } This is highly simplified of course. So the way it works is that this JSON structure is read from the client scope or the database and then for any method for a particular form element, its corresponding CFC is called. For example, we loop over the collection of fields and call the corresponding CFC in the application scope passing the entire formModel and the individual node (by reference): application.form.elems.Select.render(formModel,node) Within the Select.cfc component we act on arguments.node and update it and update the formModel. Its kind of like a pseudo object-orientated design. In fact, it corresponds to a real OOP model on the client side where Select.js is an instantiated class. On a single request to generate a form for example, there may be something like 100 method calls on various application scoped CFC's, all passing in what can be a large formModel structure. So my question is, does anyone see anything inherently evil in this design. Is there a performance hit for invoking so many CFC methods (they are all app scoped). I will be doing some load testing shortly, but wanted to see what the general consensus was. On that note, if any one specializes in load testing and optimization of CF apps - please contact me offlist.. Brook Davies Logiforms.com ~| Order the Adobe Coldfusion Anthology now! http://www.amazon.com/Adobe-Coldfusion-Anthology-Michael-Dinowitz/dp/1430272155/?tag=houseoffusion Archive: http://www.houseoffusion.com/groups/cf-talk/message.cfm/messageid:335303 Subscription: http://www.houseoffusion.com/groups/cf-talk/subscribe.cfm Unsubscribe: http://www.houseoffusion.com/groups/cf-talk/unsubscribe.cfm
Re: How Many CFCs is too many CFCs
How you are encapsulating your cfc's. It there only one remote object that interacts with the client and everything else is private/public? ~| Order the Adobe Coldfusion Anthology now! http://www.amazon.com/Adobe-Coldfusion-Anthology-Michael-Dinowitz/dp/1430272155/?tag=houseoffusion Archive: http://www.houseoffusion.com/groups/cf-talk/message.cfm/messageid:335307 Subscription: http://www.houseoffusion.com/groups/cf-talk/subscribe.cfm Unsubscribe: http://www.houseoffusion.com/groups/cf-talk/unsubscribe.cfm
Re: How Many CFCs is too many CFCs
I took a quick read through your email and couldn't find anything inherently wrong with the design IMHO. Having 60 objects in the application scope I presume is analogous to saying you have 60 singletons. Let's say you have 10 simultaneous requests at any given point. It's better to have 60 object instances than 600 which is what you'd get if you put them in the request scope or somewhere else. I also don't see any real issue to having 60 lightweight objects vs. 20 where each one is 3x as large. They aren't going to multiply as the server loads up. Using application-scoped objects means that you will need to be very sure you are scoping all your variables correctly to avoid bugs. Also, be sure you're not adding persistent objects like session or application objects into any other objects like your request object. I've had JVM GC issues when I've done that as it seems that the request objects aren't garbage-collected properly as they contain objects in the session or application scope. Make sure your variables are scoped properly, make sure you're not mixing your persistent and non-persistent scopes together (like copying application.foo into request.bar.foo) and you should be fine. - Andrew. On 2010-07-13, at 15:13, Brook Davies wrote: Hi folks, I need to ask what you more experienced folks thing about my application design. I have some reservations about the number of CFC's loaded into the application scope and the number of calls to CFC methods per request. Background: -Client variable DB storage -Not able to use session vars -2 web servers -60+ CFC's loaded into the application scope -Application is for form design software (like a simplified web based Adobe Designer sort of thing..) On the front end (ExtJS) the client builds a form by adding textfields, selects, radios etc. This creates a JSON packet on the server side that describes the form model. Example: { Formname:'myform', Id:'123', isSecure:true, children:[ { class:'TextField', name:'First Name', id:'123' } , { Class:'Select', Name:'Province', Options:['BC','AL'] } ] } This is highly simplified of course. So the way it works is that this JSON structure is read from the client scope or the database and then for any method for a particular form element, its corresponding CFC is called. For example, we loop over the collection of fields and call the corresponding CFC in the application scope passing the entire formModel and the individual node (by reference): application.form.elems.Select.render(formModel,node) Within the Select.cfc component we act on arguments.node and update it and update the formModel. Its kind of like a pseudo object-orientated design. In fact, it corresponds to a real OOP model on the client side where Select.js is an instantiated class. On a single request to generate a form for example, there may be something like 100 method calls on various application scoped CFC's, all passing in what can be a large formModel structure. So my question is, does anyone see anything inherently evil in this design. Is there a performance hit for invoking so many CFC methods (they are all app scoped). I will be doing some load testing shortly, but wanted to see what the general consensus was. On that note, if any one specializes in load testing and optimization of CF apps - please contact me offlist.. Brook Davies Logiforms.com ~| Order the Adobe Coldfusion Anthology now! http://www.amazon.com/Adobe-Coldfusion-Anthology-Michael-Dinowitz/dp/1430272155/?tag=houseoffusion Archive: http://www.houseoffusion.com/groups/cf-talk/message.cfm/messageid:335309 Subscription: http://www.houseoffusion.com/groups/cf-talk/subscribe.cfm Unsubscribe: http://www.houseoffusion.com/groups/cf-talk/unsubscribe.cfm
Re: How Many CFCs is too many CFCs
Let me make a completely useless aside: The abbreviation for Alberta is AB not AL? On Tue, Jul 13, 2010 at 3:13 PM, Brook Davies br...@logiforms.com wrote: Hi folks, I need to ask what you more experienced folks thing about my application design. I have some reservations about the number of CFC's loaded into the application scope and the number of calls to CFC methods per request. Background: -Client variable DB storage -Not able to use session vars -2 web servers -60+ CFC's loaded into the application scope -Application is for form design software (like a simplified web based Adobe Designer sort of thing..) On the front end (ExtJS) the client builds a form by adding textfields, selects, radios etc. This creates a JSON packet on the server side that describes the form model. Example: { Formname:'myform', Id:'123', isSecure:true, children:[ { class:'TextField', name:'First Name', id:'123' } , { Class:'Select', Name:'Province', Options:['BC','AL'] } ] } This is highly simplified of course. So the way it works is that this JSON structure is read from the client scope or the database and then for any method for a particular form element, its corresponding CFC is called. For example, we loop over the collection of fields and call the corresponding CFC in the application scope passing the entire formModel and the individual node (by reference): application.form.elems.Select.render(formModel,node) Within the Select.cfc component we act on arguments.node and update it and update the formModel. Its kind of like a pseudo object-orientated design. In fact, it corresponds to a real OOP model on the client side where Select.js is an instantiated class. On a single request to generate a form for example, there may be something like 100 method calls on various application scoped CFC's, all passing in what can be a large formModel structure. So my question is, does anyone see anything inherently evil in this design. Is there a performance hit for invoking so many CFC methods (they are all app scoped). I will be doing some load testing shortly, but wanted to see what the general consensus was. On that note, if any one specializes in load testing and optimization of CF apps - please contact me offlist.. Brook Davies Logiforms.com ~| Order the Adobe Coldfusion Anthology now! http://www.amazon.com/Adobe-Coldfusion-Anthology-Michael-Dinowitz/dp/1430272155/?tag=houseoffusion Archive: http://www.houseoffusion.com/groups/cf-talk/message.cfm/messageid:335327 Subscription: http://www.houseoffusion.com/groups/cf-talk/subscribe.cfm Unsubscribe: http://www.houseoffusion.com/groups/cf-talk/unsubscribe.cfm