ColdFusion / IIS / Redirect Limit? - iis

I have a ColdFusion script which performs a task and then redirects to itself using the <cflocation> tag, passing in the next ID to be processed. The script stops working after EXACTLY 51 rows. I thought it was a bug in the code, so I updated the ID to be process to 52, and it runs from ID 52 through 102 and stops. Again, 51 rows exactly.
does anyone know if there is some limit in ColdFusion on the cflocation tag? Or could this be something IIS is doing?
When I use JavaScript window.location method, it works fine and does not stop until the end - as expected.
Updated - Explanation
The reason the script redirects to itself after each ID is processed is because ColdFusion does not release variables/memory back to the JVM until after the request is complete. So, for a request that performs several hundred complicated tasks, the memory usage continues to grow until the request officially completes. This causes an ERROR OUT OF MEMORY in the JVM. From what I understand, the best way to correct this is to split the items out into separate requests, that way ColdFusion will release the request variables/memory back to the JVM. Thus, why we are processing 1 item and then redirecting to self passing in the next ID to process. This is to keep ColdFusion seeing the requests as unique and keep memory consumption down.

It's an "ugly hack" but, maybe you'd like to try in case you can't find another option.
I was able to test and run this until completion as a scheduled task by executing curl from ColdFusion, so it requires curl available.
<cfparam name="url.id" default="0" />
<cfset url.id = url.id + 1 />
<!--- // your task code --->
<cffile
action = "append"
file = "C:\inetpub\wwwroot\foo\redir-log.txt"
output = '#url.id#'>
<!--- // your task code --->
<!--- // condition to end the loop --->
<cfif (url.id lt 300)>
<cfset args = [
'http://127.0.0.1:53227/redir.cfm?id=#url.id#'
] />
<cfexecute
name="curl"
arguments="#args#"
variable="output"
errorVariable="error"
timeout="0"
/>
<cfdump var="#output#" />
<hr />
<cfdump var="#error#" />
<hr />
</cfif>

I am not sure about a limit being there in ColdFusion/IIS, but I think browsers have a fail safe in order to restrict infinite loop. In my browser(Chrome), it seems the limit is 19.
The ways to overcome this is to make sure that the HTML loads, so that we do not confuse the session. Then redirect using either of the following.
window.location
<meta http-equiv="refresh" content="0;url=http://example.com">.

Related

Primefaces poll stops working when the server sends an empty response

I use the poll component from Primefaces 4.0 to make a request to the server every 10 minutes. Everything works just fine most of the time, but every now and then, I don't know why, the server returns an empty response with a 200 code (OK). This is a 100% empty response. A 0 bytes length response. So the PrimeFaces.ajax.AjaxResponse method gets a null value as parameter, and when it tries to access the documentElement property of this object, I get an error "Uncaught TypeError: Cannot read property documentElement of null" and everything stops working.
I don't know why I get empty responses, maybe its a problem in the network, or maybe it's a problem with the cluster in which the app is running, or maybe is the proxy; but the sysadmin doesn't care a lot about it, and so, I need to find a software solution.
Is there anything I can do which doesn't involve editing Primefaces' own files?
Thank you very much for any help you can give me!
In case someone is wondering, I ended overwriting PrimeFaces.ajax.AjaxResponse, checking whether the response is empty and calling the original method if everything is right
OriginalAjaxResponse = PrimeFaces.ajax.AjaxResponse;
PrimeFaces.ajax.AjaxResponse = function (responseXML) {
if (responseXML != null)
OriginalAjaxResponse(responseXML);
}
It's not pretty, but it works
I had same problem yesterday and i find this blogpost which tells us to move h:outputStylesheet and h:outputScript to end of body.
<h:outputStylesheet library="css" name="main.css" />
<h:outputScript library="js" name="primefaces.locales.js"/>
http://maxyermayank.blogspot.com.tr/2013/10/jsf-ajax-response-returning-empty.html?showComment=1454339705279

how to make sure a Coldfusion object is only created once?

I have a scheduled task which should run every minute. To block the file from being called from outside, I want to compare host and calling IP adress like so:
<cfif NOT structKeyExists( "variables", caller )>
<cfset variables.caller = createObject("java", "java.net.InetAddress")>
</cfif>
<cfif variables.caller.getLocalHost().getHostAddress() EQ cgi.remote_addr>
// run task
</cfif>
Question:
I'm not really used to working with objects in Coldfusion, so would this be a way to make sure the object is created once and re-created every minute when the task is being called? Since this is running in my admin section, should I create the object on application scope right away?
Thanks for some input!
When you run a request even if the request is a scheduled task, all the variables are destroyed when the request has been completed. Only variables like session, application, and server persist between requests.
One approach to making sure that pages only run on the machine that they are on is to:
<cfif cgi.remote_addr EQ "127.0.0.1">
// run task
</cfif>

Reducing NUMBER_OF_VIEWS_IN_SESSION results in ViewExpiredException

I'm running myFaces 2.1.7 and desperatly trying to reduche the mmeory usage of our web application. Basically session size of each users ballons to up to 10MB which we can't handle.
I tried adding the following to Descriptor:
<context-param>
<param-name>org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION</param-name>
<param-value>3</param-value>
</context-param>
result was ok and the session size of any given user wasn't going higher than 1MB. But then alot of users aren't able to login since the change. What is happening is that on login screen ViewExpiredException is thrown , and i wrote a custom viewExpiredException class that redirects the user back to login screen, so essentially they're stuck on login screen loop
try to log in ---> ViewExpiredException thrown ---> Custom ViewExpiredHandler ----> Forward user to Login Screen
<----------------------------------------------------------------------------------------------------------------
Removing the above context-param fixes the issue! My question is one -
1) why is the viewException is thrown when the NUMBER_OF_VIEWS_IN_SESSION is reduced from its default value
2) is it possible to work around the issue by using the custom ViewExpiredHandler class ? how?
3) am i doing something wrong in causing this issue?
P.S. in testing why this is happening, if i open for example IE and try to login all is ok, but then if i try to open another browser (e.g. chrome) and login using another username above issues are encountered mirroring issues reported by users not being able to login.
Also following hints of myFaces wiki i have added the following to descriptor but i don't believe it can contribute to the issue:
<context-param>
<param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>
<param-value>false</param-value>
</context-param>
Update:
As suggested by BalusC i change the STATE_SAVING_METHOD to client in order to resolve the memory issues we are having . immediately all UAT testers reported dramatic slow down on all page load speeds so i had to revert back to having STATE_SAVING_METHOD set to server.
Since I've been experimenting with value of org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION and with the current value of 6 (an improvement of 70% over the default 20 sessions) i am not getting the ViewExpiredException errors any more.(reason why this question was created originally)
But in a way i am playing russian roulette. I don't really know why having the value of org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION set to 3/4/5 didn't work and why 6 is working and it bothers me not being able to explain it. Is anyone able to provide information?
I originally asked this question after noticing how the use of browser's BACK button was causing ViewExpired Exception to be thrown.
I had also reduced the default value of 20 for org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION to 3 and then 6 (in trying memory foot print) which aggravated the problem.
Having wrote a ViewExpired Exception Handler, i was now looking for a way to do something about the Exception when it was thrown and below is how i am dealing with it:
1 - `org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION ` value is 6
2 - when ViewExpired Exception is thrown in ViewExpired Handler retrieve the request URL
HttpServletRequest orgRequest = (HttpServletRequest) fc.getExternalContext().getRequest();
3 - insert a boolean into user session (used as flag to be used below)
Map<String, Object> sessionMap = FacesContext.getCurrentInstance()
.getExternalContext().getSessionMap();
sessionMap.put("refreshedMaxSesion",true);
4 - redirect back to URL retrieved in step 2
fc.getExternalContext().redirect(orgRequest.getRequestURI());
5 - Since page is reloaded , see if the flag in step 3 exists and if so flag a notification to be shown to user and remove from session
if(sessionMap.containsKey("refreshedMaxSesion")){
showPageForceRefreshed = true;
sessionMap.remove("refreshedMaxSesion");
}
6 - I'm using Pines Notify to show subtle "FYI, this page way refreshed" type message".
<h:outputText rendered="#{ myBean.showPageForceRefreshed }" id="PageWasRefreshedInfoId" >
<script type="text/javascript">
newjq(document).ready(function(){
newjq.pnotify({
pnotify_title: 'Info',
pnotify_text: 'Ehem, Page was Refreshed.' ,
pnotify_mouse_reset: false,
pnotify_type: 'info',
pnotify_delay: 5000
});
});
</script>
</h:outputText>

Memory Leak Looping cfmodule inside cffunction

Googlers if you've got a heap dump with a root of coldfusion.runtime.CFDummyComponent read on.
Update 2/22/2011
Marc Esher of MXUnit fame found the exact same bug in a different context. His solution involves a large loop over a query solved by going from query="name" to from="1" to="#name.recordcount#" index="row". Another approach that works is using <cfthread> inside the loop as such:
<cfloop ...>
<cfset threadName = "thread" & createUuid()>
<cfthread name="#threadName#">
<!--- do stuff --->
</cfthread>
<cfthread action="join" name="#threadName#">
</cfloop>
This is very effective when you run into situations where you need to do things inside the loop like queries and <cfmodule> inside <cffunction> so that the memory consumed is only for that iteration.
Old Question
Hoping someone else can confirm or tell me what I'm doing wrong. I am able to consistently reproduce an OOM running by calling the file oom.cfm (shown below). Using jconsole I am able to see the request consumes memory and never releases it until complete. The issue appears to be calling <cfmodule> inside of <cffunction>, where if I comment out the <cfmodule> call things are garbage collected while the request is running.
ColdFusion version: 9,0,1,274733
JVM Arguments
java.home=C:/Program Files/Java/jdk1.6.0_18
java.args=-server -Xms768m -Xmx768m -Dsun.io.useCanonCaches=false -XX:MaxPermSize=512m -XX:+UseParallelGC -Xbatch -Dcoldfusion.rootDir={application.home}/ -Djava.security.policy={application.home}/servers/41ep8/cfusion.ear/cfusion.war/WEB-INF/cfusion/lib/coldfusion.policy -Djava.security.auth.policy={application.home}/servers/41ep8/cfusion.ear/cfusion.war/WEB-INF/cfusion/lib/neo_jaas.policy -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=56033
Test Case
oom.cfm (this calls template.cfm below - Adobe Bug #85736)
<cffunction name="fun" output="false" access="public" returntype="any" hint="">
<cfset var local = structNew()/>
<!--- comment out cfmodule and no OOM --->
<cfmodule template="template.cfm">
</cffunction>
<cfset size = 1000 * 200>
<cfloop from="1" to="#size#" index="idx">
<cfset fun()>
<cfif NOT idx mod 1000>
<cflog file="se-err" text="#idx# of #size#">
</cfif>
</cfloop>
template.cfm
<!--- I am empty! --->
Update #2 (cfthread case from Elliott Sprehn - Adobe ColdFusion Bug #83359)
<cfthread name="test">
<cfloop from="1" to="10000" index="i">
<cflog text="This is very bad.">
<cflock name="test" timeout="10">
</cflock>
</cfloop>
<!--- Sleep a very long time (10 minutes) --->
<cfset sleep(600000)>
</cfthread>
I've not run into this before, but here's what I think is going on:
Each time cfmodule is called, a new memory space is created for it (which, IIRC, is the main difference between it and cfinclude).
Because you are calling the cfmodule within the function, the cfmodule memory space technically belongs to that function's memory space.
The function's memory is protected from garbage collection until the function is done.
Result: heap fills, and you get an OOM error.
I don't think calling this a memory leak is correct, as it is behaving correctly, and when the function completes, the garbage collector can clear the hold on that memory. However, I can see how it might be inconvenient.
This problem manifests with lots of tags unfortunately. I've seen this with cflock inside cfthread. Write a very long running loop in a cfthread that uses cflock, you'll run out of memory eventually. It takes a long time, but it happens. I bet the retention problem exists in regular requests too, but you don't usually have a loop that runs hundreds of thousands of times with a cflock inside so no one notices.
I reported this bug a long time ago, but it never got fixed:
http://www.elliottsprehn.com/cfbugs/bugs/83359
The best solution for now is to not use cfmodule inside a loop like this. Custom tags really weren't intended for calling 20k times in a single request. You're going to want to use UDFs instead. cfmodule is extremely expensive anyway and using a UDF will be noticeably faster.
Here is a discussion of a possibly related Coldfusion version 9 cfc memory leak problem: http://forums.adobe.com/thread/1034324?start=0&tstart=0
See this bug report on it: https://bugbase.adobe.com/index.cfm?event=bug&id=3124148
I don't believe Adobe released a fix for verion 9.01 but supposedly this problem is fixed in version 10. There are workarounds for most people (depending on the scope of their problem) for this not unlike what's been described here.

ColdFusion threads: looping session variables + sleep

hey guys I'm trying to create a timer which counts the time spent on a page using a thread heres what I have so far:
<cfset session.time=0>
<cfthread name="timer" action="run">
<cfscript>
counter = 0;
while (counter <9000) {
sleep(1000);
session.time++;
counter ++;
}
</cfscript>
</cfthread>
page 2:
<cfoutput>#session.time#</cfoutput>
page 2 gives me 0 every time anyone see a problem?
edit:
I changed line 1 of my code to <cfset session.time=100> and now page 2 says 100, its like the stuff inside the cfscript loop isn't reassigning session.time
This works for me.
Are you sure you are using the Developer or Enterprise edition of ColdFusion and the threads have actually kicked off? I think only those editions support multi-threading.
One way to do verity your threads working is to use cfstat - you should see one request running even though your page has returned.
Another is to write output from your spawned thread - use the code snipped below to write to System.out - ideally you'll need to have CF running as a console task to do this.
<cfset session.time=0 />
<cfthread name="timer" action="run">
<cfscript>
counter = 0;
while (counter <9000) {
sleep(1000);
session.time++;
sys = createObject("java", "java.lang.System");
sys.out.println("*** [DEBUG] - #timeformat(now(),'HH:mm:ss' )# - session.time=#session.time# ");
counter ++;
}
</cfscript>
</cfthread>
Your code works fine for me. You have got an Application.cfm page setup to enable session management i.e:
<cfapplication name="#hash(getCurrentTemplatePath())#"
sessiontimeout="#createTimeSpan(0,0,20,0)#" sessionmanagement="true"/>
Code executed inside a thread has its own scope, including session. I would set a variable within the tread and then access it from within the threads scope.
i.e.
Change session.time++; to thread.time++; and then use cfthread[timer].time to get the thread's time.
Although this may not hold if you enable session management like some of the other posts discuss.

Resources