RE: Caching CFC's
Is the constructor in a CFC always called in CFMX when you call a method in that CFC? That's seems a bit odd to me. In my imagination, I only call the init method once, when I create the object in the application scope. After that the init is not directly invoked by me. The second example does though, but that one was merely a test to see the difference in datetime. Micha Schopman Software Engineer Modern Media, Databankweg 12 M, 3821 ALAmersfoort Tel 033-4535377, Fax 033-4535388 KvK Amersfoort 39081679, Rabo 39.48.05.380 [Todays Threads] [This Message] [Subscription] [Fast Unsubscribe] [User Settings] [Donations and Support]
RE: Caching CFC's
Nevermind, I see what you mean, it was a bug in the second part. That line should only call init on the IOFactory in the variables scope. Micha Schopman Software Engineer Modern Media, Databankweg 12 M, 3821 ALAmersfoort Tel 033-4535377, Fax 033-4535388 KvK Amersfoort 39081679, Rabo 39.48.05.380 [Todays Threads] [This Message] [Subscription] [Fast Unsubscribe] [User Settings] [Donations and Support]
Caching CFC's
Is this a correct way of caching a CFC, for future reuse and preventing useless IO traffic? I never tried this approach in production but I don't believe there are a lot of problems with this construction in terms of memory. cfapplication name=persistencyTest sessionmanagement=yes clientmanagement=no cflock scope=application type=exclusive timeout=1 cfif NOT IsDefined('application.IOFactory') !--- loaded CFC into cache --- cfset IOFactory = createObject('component','myfunction').init() cfset application.IOFactory = IOFactory cfelse !--- loaded CFC from cache for reuse without re-calling the class --- cfset IOFactory = application.IOFactory /cfif /cflock Micha Schopman Software Engineer Modern Media, Databankweg 12 M, 3821 ALAmersfoort Tel 033-4535377, Fax 033-4535388 KvK Amersfoort 39081679, Rabo 39.48.05.380 [Todays Threads] [This Message] [Subscription] [Fast Unsubscribe] [User Settings] [Donations and Support]
Re: Caching CFC's
A few things. 1) The lock isn't really necessary if you don't have any race conditions. 2) Why do you create a copy of application.IOFactory in the variables scope? You don't need to normally. I'd just have code like so: cfif not isDefined(application.foo) cfset application.foo = createObject(etc) /cffi -Ray On Thu, 22 Jul 2004 13:28:59 +0200, Micha Schopman [EMAIL PROTECTED] wrote: Is this a correct way of caching a CFC, for future reuse and preventing useless IO traffic? I never tried this approach in production but I don't believe there are a lot of problems with this construction in terms of memory. cfapplication name=persistencyTest sessionmanagement=yes clientmanagement=no cflock scope=application type=exclusive timeout=1 cfif NOT IsDefined('application.IOFactory') !--- loaded CFC into cache --- cfset IOFactory = createObject('component','myfunction').init() cfset application.IOFactory = IOFactory cfelse !--- loaded CFC from cache for reuse without re-calling the class --- cfset IOFactory = application.IOFactory /cfif /cflock Micha Schopman Software Engineer Modern Media, Databankweg 12 M, 3821 ALAmersfoort Tel 033-4535377, Fax 033-4535388 KvK Amersfoort 39081679, Rabo 39.48.05.380 [Todays Threads] [This Message] [Subscription] [Fast Unsubscribe] [User Settings] [Donations and Support]
RE: Caching CFC's
The lock I placed here was more like a simulation of what I wanted to do, code within could crash on race conditions (although that should be impossible with a correct CFC). The reason why I copy the application,scopeinto a variables scope, is to use the CFC throughout the application without the need to relock again with a type=read to access the methods (in case of race conditions). I also could just call the application scope, without locking, but It has become common since I still work a lot with CF5, and less with CFMX due to company management decisions. But you're right in terms of, when race conditions do not affect the cfc, the locking is unneeded. (also because cfmx has fixed locking memory leaks). I thought about this technique because I use a framework which is very much build upon a single file which checks for locations of files, inheritance, overriding for customers, etc. and this file is called about 6 times per request. So I thought, why recall that file (*.cfc) again and again while the contents are exactly the same. Every customer uses a specific directory to read files from, but these files get overrided when the customer has a file with the exact name in its own directory. This structure is cached in a struct, and it would be great if I can create some sort of persistency for the duration of the application scope, without calling the CFC on each request, but instead calling the code in memory for each request. It was merely a thought about in memory processing of code, which ofcourse is the fastest way of processing code, but I do not have a clue if this could lead to unwanted errors :-) Micha Schopman Software Engineer Modern Media, Databankweg 12 M, 3821 ALAmersfoort Tel 033-4535377, Fax 033-4535388 KvK Amersfoort 39081679, Rabo 39.48.05.380 [Todays Threads] [This Message] [Subscription] [Fast Unsubscribe] [User Settings] [Donations and Support]
RE: Caching CFC's
Micha, If I remember the code you sent correctly -- you didn't copy anything anywhere, remember that CFCs/structs and others are only copied by reference, you need Duplicate() to do that. I think you lose some of the point with the caching, as well, by copying the whole cfc. What you should do -- make sure that the component doesn't store any instance data after init(), and if they do, then it should be locked. And make sure the component is thread safe. -- Hugo Ahlenius - Hugo AhleniusE-Mail: [EMAIL PROTECTED] Project Officer Phone:+46 8 230460 UNEP GRID-ArendalFax:+46 8 230441 Stockholm OfficeMobile:+46 733 467111 WWW: http://www.grida.no - | -Original Message- | From: Micha Schopman [mailto:[EMAIL PROTECTED] | Sent: Thursday, July 22, 2004 14:16 | To: CF-Talk | Subject: RE: Caching CFC's | | The lock I placed here was more like a simulation of what I | wanted to do, code within could crash on race conditions | (although that should be impossible with a correct CFC). | | The reason why I copy the application,scopeinto a variables | scope, is to use the CFC throughout the application without | the need to relock again with a type=read to access the | methods (in case of race conditions). I also could just call | the application scope, without locking, but It has become | common since I still work a lot with CF5, and less with CFMX | due to company management decisions. But you're right in | terms of, when race conditions do not affect the cfc, the | locking is unneeded. (also because cfmx has fixed locking | memory leaks). | | I thought about this technique because I use a framework | which is very much build upon a single file which checks for | locations of files, inheritance, overriding for customers, | etc. and this file is called about 6 times per request. So I | thought, why recall that file (*.cfc) again and again while | the contents are exactly the same. Every customer uses a | specific directory to read files from, but these files get | overrided when the customer has a file with the exact name in | its own directory. This structure is cached in a struct, and | it would be great if I can create some sort of persistency | for the duration of the application scope, without calling | the CFC on each request, but instead calling the code in | memory for each request. | | It was merely a thought about in memory processing of code, | which ofcourse is the fastest way of processing code, but I | do not have a clue if this could lead to unwanted errors :-) | Micha Schopman Software Engineer Modern Media, Databankweg 12 | M, 3821 ALAmersfoort Tel 033-4535377, Fax 033-4535388 KvK | Amersfoort 39081679, Rabo 39.48.05.380 | | | [Todays Threads] [This Message] [Subscription] [Fast Unsubscribe] [User Settings] [Donations and Support]
RE: Caching CFC's
So I merely created a pointer ... ... erm .. oops? .. It is kunda frustrating working with CF since the betas but never being able to work with CFMX because management denied it based on the risc. now is the time to strike back ;) My hope is on a quite big improvement in processing requests when using CFC's. Micha Schopman Software Engineer Modern Media, Databankweg 12 M, 3821 ALAmersfoort Tel 033-4535377, Fax 033-4535388 KvK Amersfoort 39081679, Rabo 39.48.05.380 [Todays Threads] [This Message] [Subscription] [Fast Unsubscribe] [User Settings] [Donations and Support]
Re: Caching CFC's
One problem though - Duplicate doesn't work on CFCs. Sure, it doesn't throw an error, but it doesn't copy it correctly. Ditto for CFWDDX. You can serialize a CFC but your packet can't be deserialized correctly. -Ray On Thu, 22 Jul 2004 14:50:58 +0200, Hugo Ahlenius [EMAIL PROTECTED] wrote: Micha, If I remember the code you sent correctly -- you didn't copy anything anywhere, remember that CFCs/structs and others are only copied by reference, you need Duplicate() to do that. I think you lose some of the point with the caching, as well, by copying the whole cfc. What you should do -- make sure that the component doesn't store any instance data after init(), and if they do, then it should be locked. And make sure the component is thread safe. -- Hugo Ahlenius - Hugo AhleniusE-Mail: [EMAIL PROTECTED] Project Officer Phone:+46 8 230460 UNEP GRID-ArendalFax:+46 8 230441 Stockholm OfficeMobile:+46 733 467111 WWW: http://www.grida.no - | -Original Message- | From: Micha Schopman [mailto:[EMAIL PROTECTED] | Sent: Thursday, July 22, 2004 14:16 | To: CF-Talk | Subject: RE: Caching CFC's | | The lock I placed here was more like a simulation of what I | wanted to do, code within could crash on race conditions | (although that should be impossible with a correct CFC). | | The reason why I copy the application,scopeinto a variables | scope, is to use the CFC throughout the application without | the need to relock again with a type=read to access the | methods (in case of race conditions). I also could just call | the application scope, without locking, but It has become | common since I still work a lot with CF5, and less with CFMX | due to company management decisions. But you're right in | terms of, when race conditions do not affect the cfc, the | locking is unneeded. (also because cfmx has fixed locking | memory leaks). | | I thought about this technique because I use a framework | which is very much build upon a single file which checks for | locations of files, inheritance, overriding for customers, | etc. and this file is called about 6 times per request. So I | thought, why recall that file (*.cfc) again and again while | the contents are exactly the same. Every customer uses a | specific directory to read files from, but these files get | overrided when the customer has a file with the exact name in | its own directory. This structure is cached in a struct, and | it would be great if I can create some sort of persistency | for the duration of the application scope, without calling | the CFC on each request, but instead calling the code in | memory for each request. | | It was merely a thought about in memory processing of code, | which ofcourse is the fastest way of processing code, but I | do not have a clue if this could lead to unwanted errors :-) | Micha Schopman Software Engineer Modern Media, Databankweg 12 | M, 3821 ALAmersfoort Tel 033-4535377, Fax 033-4535388 KvK | Amersfoort 39081679, Rabo 39.48.05.380 | | | [Todays Threads] [This Message] [Subscription] [Fast Unsubscribe] [User Settings] [Donations and Support]
Re: Caching CFC's
One other thing about storing the cfc in the application scope was that any changes to the CFC wouldn't be reflected until the application re-started. So I'd also consider adding something like this: cfif NOT IsDefined('application.IOFactory') OR (isDefined(url.killApp) AND url.killApp eq yes) ... So that you can easily re-create all your objects G On Thu, 22 Jul 2004 13:28:59 +0200, Micha Schopman [EMAIL PROTECTED] wrote: Is this a correct way of caching a CFC, for future reuse and preventing useless IO traffic? I never tried this approach in production but I don't believe there are a lot of problems with this construction in terms of memory. cfapplication name=persistencyTest sessionmanagement=yes clientmanagement=no cflock scope=application type=exclusive timeout=1 cfif NOT IsDefined('application.IOFactory') !--- loaded CFC into cache --- cfset IOFactory = createObject('component','myfunction').init() cfset application.IOFactory = IOFactory cfelse !--- loaded CFC from cache for reuse without re-calling the class --- cfset IOFactory = application.IOFactory /cfif /cflock Micha Schopman Software Engineer Modern Media, Databankweg 12 M, 3821 ALAmersfoort Tel 033-4535377, Fax 033-4535388 KvK Amersfoort 39081679, Rabo 39.48.05.380 [Todays Threads] [This Message] [Subscription] [Fast Unsubscribe] [User Settings] [Donations and Support]
RE: Caching CFC's
Always.. there are more caching system involved in the application, but since it is production the only time you have to flush them is when you change framework files. Micha Schopman Software Engineer Modern Media, Databankweg 12 M, 3821 ALAmersfoort Tel 033-4535377, Fax 033-4535388 KvK Amersfoort 39081679, Rabo 39.48.05.380 [Todays Threads] [This Message] [Subscription] [Fast Unsubscribe] [User Settings] [Donations and Support]
RE: Caching CFC's
I tested a combination, one object created in the application scope, and one in the variables scope: In both outputs, I get the exact same time. In the application scope I thought it would be set in the CFC, so next time I would call the CFC I would get the old time back. The second CFC should always output the current time. Unfortunately the time is not save in the application scope. This indeed means a pointer. Does someone now ways to do some CFC caching? CFM Page cfapplication name=persistencyTest sessionmanagement=yes clientmanagement=no cfif NOT IsDefined('application.IOFactory') cfset application.IOFactory = createObject('component','myfunction') cfset application.IOFactory.init() /cfif cfoutput#application.IOFactory.mymethod()#/cfoutput cfset IOFactory = createObject('component','myfunction') cfset application.IOFactory.init() cfoutput#IOFactory.myMethod()#/cfoutput MyFunction.cfc cfcomponent output=yes cfset init() cffunction name=init access=public returntype=date cfset this.datetimestamp = Now() cfreturn this.datetimestamp /cffunction cffunction name=mymethod access=public returntype=date cfreturn this.datetimestamp /cffunction /cfcomponent Micha Schopman Software Engineer Modern Media, Databankweg 12 M, 3821 ALAmersfoort Tel 033-4535377, Fax 033-4535388 KvK Amersfoort 39081679, Rabo 39.48.05.380 [Todays Threads] [This Message] [Subscription] [Fast Unsubscribe] [User Settings] [Donations and Support]
Re: Caching CFC's
On every request you are rerunning init on the application.IOFactory object. Therefore it makes sense that your time values match. Remove that line and it should work fine. On Thu, 22 Jul 2004 16:01:14 +0200, Micha Schopman [EMAIL PROTECTED] wrote: I tested a combination, one object created in the application scope, and one in the variables scope: In both outputs, I get the exact same time. In the application scope I thought it would be set in the CFC, so next time I would call the CFC I would get the old time back. The second CFC should always output the current time. Unfortunately the time is not save in the application scope. This indeed means a pointer. Does someone now ways to do some CFC caching? CFM Page cfapplication name=persistencyTest sessionmanagement=yes clientmanagement=no cfif NOT IsDefined('application.IOFactory') cfset application.IOFactory = createObject('component','myfunction') cfset application.IOFactory.init() /cfif cfoutput#application.IOFactory.mymethod()#/cfoutput cfset IOFactory = createObject('component','myfunction') cfset application.IOFactory.init() cfoutput#IOFactory.myMethod()#/cfoutput MyFunction.cfc cfcomponent output=yes cfset init() cffunction name=init access=public returntype=date cfset this.datetimestamp = Now() cfreturn this.datetimestamp /cffunction cffunction name=mymethod access=public returntype=date cfreturn this.datetimestamp /cffunction /cfcomponent Micha Schopman Software Engineer Modern Media, Databankweg 12 M, 3821 ALAmersfoort Tel 033-4535377, Fax 033-4535388 KvK Amersfoort 39081679, Rabo 39.48.05.380 [Todays Threads] [This Message] [Subscription] [Fast Unsubscribe] [User Settings] [Donations and Support]
Re: Caching CFC's
Does someone now ways to do some CFC caching? Storing CFCs, including instance data, in the Session scope certainly seems to work for me - I imagine Application would be the same. I do it very simply like this: cfif not isDefined(Session.cfcInstanceName) cfobject component=cfcName name=Session.cfcInstanceName !--- invoke all the methods that set up the persistent data --- /cfif cfinvoke component=#Session.cfcInstanceName# ... Nick [Todays Threads] [This Message] [Subscription] [Fast Unsubscribe] [User Settings] [Donations and Support]
Re: Caching CFC's
On Thu, 22 Jul 2004 14:16:20 +0200, Micha Schopman [EMAIL PROTECTED] wrote: The reason why I copy the application,scopeinto a variables scope, is to use the CFC throughout the application without the need to relock again with a type=read to access the methods In my opinion, the only sorts of objects you should store in application scope are service CFCs - i.e., stateless ones - so there couldn't be a race condition because stateless CFCs have no instance data, except perhaps refreshable cached data. This structure is cached in a struct, and it would be great if I can create some sort of persistency for the duration of the application scope, without calling the CFC on each request, but instead calling the code in memory for each request. If the structure is modified per-user, then store the CFC in session scope instead of application scope (so each user gets their own copy) and you should be just fine. -- Sean A Corfield -- http://www.corfield.org/blog/ If you're not annoying somebody, you're not really alive. -- Margaret Atwood [Todays Threads] [This Message] [Subscription] [Fast Unsubscribe] [User Settings] [Donations and Support]