We are moving from Adobe ColdFusion 8 to 10.
We have applications using Application.cfm. We decided to start using Application.cfc as it offers more customized approach.
I was checking on how to convert Application.cfm to Application.cfc and noticed that Application.cfc with same amount of code as in Application.cfm takes more execution time than when using Application.cfm.
For example if Application.cfm takes 150ms, Application.cfc takes 630ms.
Is that how it is?
I did not go into any other detail. Please let me know if you need more details.
Thanks.
I have found application.cfc to run faster than application.cfm, but it's been years since I've used application.cfm. I would tend to agree with Adrian that it might be your code.
You can use getTickCount() to track how long sections of your code are taking to run.
The example below would track the runtime of the entire request. You would need to log or output the final value of local.loadTime. You can calculate the difference between a tickCount before and after any block of code to see how long it took to execute.
boolean function onRequestStart() {
request.startTime = getTickCount();
return true;
}
void function onRequestEnd() {
if (structKeyExists(request, "startTime") && request.startTime > 0) {
local.loadTime = getTickCount() - request.startTime;
}
}
Related
I am facing the following issue: In our project, we have a main class with a main method called "run". This method calls hundreds of other functions, classes etc.
We are now calling this run method in a test in a for loop multiple times, something like that:
for(float test_time = 0; test_time < 10.0; test_time += 0.005){
outputStruct = mainClass.run(inputStruct);
}
I now want to save all local variables of all functions and methods and all member variables of all included objects that are seen when this for loop is executed. And I want to have a snapshot of this for each loop iteration. So in this example, there should be like 2000 snapshots of all my variables.
Is this somehow possible? I see that GDB has some "trace" functionality, but it's not clear for me how I can tell GDB that it should save everything that was "seen" while executing the mainClass.run method. It should "only" remember the last state of each member and local variable. And when test_time increments, it can finalize the current snapshot and create a new one for the next time slot.
Is something like this possible? Since our usecase is some physics based scenario, it is every interesting to see how certain values change over time in a plot later. I don't mind what the format of the output file of GDB is, it will be parsed later anyway, as long as the information is somehow inside. Of course, the cleaner the file looks the better :).
Thank you for your support guys!
I have written a library I include for some security patches. In that library there are a number of CF8 and up function,attributes,etc.
I really really dont want to cut the functionality down bc adobe couldnt get it together and get this basic functionality into CF7 so Im looking to write separate lines into each function. The issue is when CF is initially reading the code it bugs out if it finds something it doesnt recognize, whether or not it is going to be called.
For example in cfdirectory CF7 doesnt support the 'type' attribute. I have a find directory function that fails in CF7 when the 'type' attribute is present and taking it out increases the search time by 10x.
<cftry>
<cfdirectory action="list" directory="#arguments.start#" name="LOCAL.dirquery" type="dir" /><!---//GET QUERY OF DIRECTORIES IN START DIRECTORY--->
<cfcatch>
<cfsetting requesttimeout="600">
<cfdirectory action="list" directory="#arguments.start#" name="LOCAL.dirquery" /><!---//GET QUERY OF DIRECTORIES IN START DIRECTORY--->
</cfcatch>
This code does not work, neither does a conditional block. Im guessing the reader cannot parse thsi into whatever language and so is failing.
The code is probably failing at compile time, not at run time (need to see the error you are receiving to know for sure). If it's a compiler error, you'll need to have break out your CF7 functions in separate components from your CF8+ functions. Then check the CF version at run time to determine which component/function to call.
Here's some pseudo code you can use in application startup to load the correct version functions into memory. That way you have a consistent interface for calling the functions anywhere in your code.
Pseudo Code:
onApplicationStart(){
if (server.coldfusion.productversion == 7){
application.cffunctions = CF7FunctionsComponent;
} else {
application.cffunctions = CF8FunctionsComponent;
}
}
Everywhere else, you call the same function regardless of CF version currently running:
application.cffunctions.doSomething();
I've written my own access layer to a game engine. There is a GameLoop which gets called every frame which lets me process my own code. I'm able to do specific things and to check if these things happened. In a very basic way it could look like this:
void cycle()
{
//set a specific value
Engine::setText("Hello World");
//read the value
std::string text = Engine::getText();
}
I want to test if my Engine-layer is working by writing automated tests. I have some experience in using the Boost Unittest Framework for simple comparison tests like this.
The problem is, that some things I want the engine to do are just processed after the call to cycle(). So calling Engine::getText() directly after Engine::setText(...) would return an empty string. If I would wait until the next call of cycle() the right value would be returned.
I now am wondering how I should write my tests if it is not possible to process them in the same cycle. Are there any best practices? Is it possible to use the "traditional testing" approach given by Boost Unittest Framework in such an environment? Are there perhaps other frameworks aimed at such a specialised case?
I'm using C++ for everything here, but I could imagine that there are answers unrelated to the programming language.
UPDATE:
It is not possible to access the Engine outside of cycle()
In your example above, std::string text = Engine::getText(); is the code you want to remember from one cycle but execute in the next. You can save it for later execution. For example - using C++11 you could use a lambda to wrap the test into a simple function specified inline.
There are two options with you:
If the library that you have can be used synchronously or using c++11 futures like facility (which can indicate the readyness of the result) then in your test case you can do something as below
void testcycle()
{
//set a specific value
Engine::setText("Hello World");
while (!Engine::isResultReady());
//read the value
assert(Engine::getText() == "WHATEVERVALUEYOUEXPECT");
}
If you dont have the above the best you can do have a timeout (this is not a good option though because you may have spurious failures):
void testcycle()
{
//set a specific value
Engine::setText("Hello World");
while (Engine::getText() != "WHATEVERVALUEYOUEXPECT") {
wait(1 millisec);
if (total_wait_time > 1 sec) // you can put whatever max time
assert(0);
}
}
In using the CF application.cfc - there is a need to create some vars to begin with (in the THIS scope) - such as this.name and this.applicationtimeout() etc.
I ran across something I consider an odd behavior - and hope someone can explain why this happens and a possible workaround.
There are quite a few "THIS" vars accepted that can work to set application specific variables (of course you have to check "allow application specific vars" in the CFADMIN - which I did)
One of these is THIS.mappings - which is an array of mappings - MINE looks something like this:
this.path = GetDirectoryFromPath( GetCurrentTemplatePath() );
this.mappings = {
'/files' = '#this.path#_my_files\'
,'/functions' = '#this.path#_my_functions\'
,'/logs' = '#this.path#_my_logs\'
};
it works fine - when it is set inside a cfscript block at the top of the application.cfc
it works fine - if I put that script block in it's own file and cfinclude it in the application.cfc
however - In an attempt to segment my code - I wanted to put ALL of my application setting in a settings.cfc... (the thought here was IF some setting had to be changed - I wouldn't have to worry about 'where' to look, I don't really want to split the THIS stuff on my app.cfc and other application or session settings in the settings.cfc
SO I created a method in the settings.cfc called getTHIS, and I put the script block there... then used
<cfinvoke component="settings"
method="getTHIS"
returnvariable="THIS"
/>
Which WORKS - except (it seems) on the mappings...
The this.name etc, all seem to work and get set - as a matter of fact the this.mappings gets set fine too (so it appears) if i do a
<cfdump var="#THIS#" label="THIS" />
The dump is identical to the dump of THIS when I set it 'literally' on the app.cfc page..
HOWEVER - any attempt to call a template thru the mapping - results in a standard "if you want to use absolute paths you have to create a mapping blah blah..."
MY BIGGER goal was (on application start) to scan a directory for sub-directories, and create mappings based on certain sub-directories.. but if I can't abstract that functionality out into it's own function - I'll be forced to write it directly in the app.cfc (which wouldn't KILL me, but again, I was trying to segment my code logically... There seems to be a limitation of when and where these mappings can be set... true?
So I guess the big question is - can I SET this.mappings thru an outside method??
I guess I could bring back the 'settings I want' using the cfc call, and then just do the 'set this.whatever = return form cfc' - (this may be my answer...)
Thanks
Mappings can only be set in the 'pseudo-constructor' and not inside any of the methods inside Application.cfc - http://adobe.ly/QN2oX1
You could try setting this.mappings to the result of a CFC call (I cannot think of why this would not work), but if it depends on a mapping to do so, it will likely not work.
I haven't tested this, but I'm pretty sure it would work if your application.cfc extends your settings.cfc.
component {
public any function getMappings() {
var mappings = {};
//code to get your directories etc.
return mappings;
}
}
component extends="settings" {
this.name = "xxxx";
this.mappings = getMappings();
...
}
NOTE: I have completely rewritten this question to take into account new information. Please reread if you've already been through this one.
I'm getting errors when using a cfthread from within a custom tag in ColdFusion 10. In the Application log, I get the following entries:
Variable _cffunccfthread_cfThreadTag2ecfm16902001291 is undefined.
The name of the function it's returning as an error is _cffunccfthread_cf[Page Name Calling the CFThreadTag] then a number that doesn't change from request to request. I can duplicate this every time with the following code:
Application.cfc:
component
{
this.name = "CFThreadCustomTagTest";
}
ThePage.cfm:
<cfthread action="run" name="ThreadTestInPage">
<cflog log="Application" text="The thread in the page successfully ran" type="information" />
</cfthread>
<cf_ThreadTag />
ThreadTag.cfm:
<cfif thisTag.ExecutionMode EQ "start">
<cfthread action="run" name="ThreadTest">
<cflog log="Application" text="The thread within the tag successfully ran" type="information" />
</cfthread>
</cfif>
Just drop all three files in a directory in ColdFusion 10 and load ThePage.cfm. I get the following entries in the Application log:
"Severity","ThreadID","Date","Time","Application","Message"
"Information","ajp-bio-8012-exec-1","06/19/12","07:18:11",,"C:\ColdFusion10\cfusion\logs\application.log initialized"
"Information","cfthread-11","06/19/12","07:18:15","CFTHREADCUSTOMTAGTEST","The thread in the page successfully ran"
"Error","cfthread-9","06/19/12","07:18:15",,"THREADTEST: Variable _cffunccfthread_cfThreadTag2ecfm16902001291 is undefined. "
I also noticed that in the error for the thread within the custom tag, it does not contain the application name. While the log entry for the thread in the page does. Notice that the error line simply has ,, for the Application column of the log, while the successful thread has "CFTHREADCUSTOMTAGTEST".
If I change ThreadTag.cfm to wait for the thread within the tag to finish processing, then everything works fine, and I get the two entries in the log as I expect:
<cfif thisTag.ExecutionMode EQ "start">
<cfthread action="run" name="ThreadTest">
<cflog log="Application" text="The thread within the tag successfully ran" type="information" />
</cfthread>
<cfthread action="join" name="ThreadTest" timeout="10" />
<cfdump var="#cfthread#">
</cfif>
And to verify that there are no funky settings anywhere, here's my local development environment's settings summary.
So it seems that if I just throw the thread out there, and don't wait for it to finish, then the thread seems to be looking for something from the parent page that is no longer in memory. At least that's my completely unfounded guess :).
I've also filed a bug with Adobe. Bug number 3218452.
I understand your predicament, but there's no actual question here.
Basically you've found a bug in CF. A few people - myself included - can replicate it.
No-one's missing anything, except for the Adobe engineers who missed including this sort of thing in their regression testing when implementing CF10. That's no indictment of them, really, as I think this is reasonably edge case, perhaps?
The "variable" CF ain't finding is actually the name of the compiled class that the CF compiler makes when compiling the code. It looks like there's a compiler bug to me.
For example, my error is this:
THREADTEST: Variable _cffunccfthread_cfThreadTag2ecfm13713410591 is undefined.
However the compiled class is:
cfThreadTag2ecfm1371341059$func_CFFUNCCFTHREAD_CFTHREADTAG2ECFM13713410591.class
I don't know what part of the class name the variable is supposed to be named for, but I suspect it should be looking for func_CFFUNCCFTHREAD_CFTHREADTAG2ECFM13713410591. Or on the other hand the compiler should not be compiling the ThreadTag.cfm file as a FUNCTION? But I'm guessing... it might need to compile the thread code as a function so as to call it in a separate thread? That's a guess. Either way: it's compiling the code as one thing, and then looking for a different thing. because of a bug.
But bottom line here: yep, you've found a bug. And you've flagged it with Adobe. I dunno what else there is for you to do here?
So basically we now know one cannot have a <cfthread> call in a custom tag (I also tested via <cfmodule>: same problem). You're gonna have to write yer code a different way, using an include or a method or something. Less than ideal, I know, but what can you do?
Footnote:
I looked at the compiled code and it looks like the problem is CF is compiling the class with that func_ prefix, but it's referring to it in its code without. I didn't follow the code all the way to checking everything that's happening, but it looks to me like there are references to it trying to load _cffunccfthread_cfThreadTag2ecfm13713410591 rather than the correct name: func_CFFUNCCFTHREAD_CFTHREADTAG2ECFM13713410591.class.
Dan,
Please look on this page:
http://help.adobe.com/en_US/ColdFusion/10.0/Developing/WSc3ff6d0ea77859461172e0811cbec0b2e1-7ff0.html
And this section "Determining the tag execution mode"
And try the equivalent mode check code <cfswitch expression=#thisTag.ExecutionMode#>
To see if this causes a different compiler code gen. Maybe it will gen code a bit different and the variable will get generated.
Also, another test to try is to put you tag first in "ThePage.cfm" and see if that causes a different code gen as well.
Finally, are you on a newer JVM, as newer ones use the latest Fork/Join features of the Java concurrency approach such as Futures, etc. and they may be causing different code gen. Maybe set your JDK to an older one and see if the code gen is different.
No real answer, but some things to look at.
I ran into this as well.
My solution was to refactor and put the cfthread stuff into a .cfc and call that from the .cfm page.