Solved

Session timeout happens inconsistently

Posted on 2004-10-01
27
393 Views
Last Modified: 2013-12-24
I have an intranet application that has been working for about 3 years.  I am using CF 5 on Win 2000.  I have been getting complaints that my users are being kicked out of the system at random times during the day.  I used to have the session timeout value set to 2 hours and have recently increased that to 9 hours to see if it would fix the problem.  I have set the max value in the CF Administrator to 9 hours as well as the code in my cfapplication page.  

I have a few questions that I've been trying to figure out:

-What would cause an application to suddenly timeout before the session variable should timeout or what would cause a session variable to timeout before the value set in the cfapplication page?

-Could it be an issue with locking session variables?  Is there a quick way to check for unlocked session variables or a way to lock all session variables?  I remember something in the CF Administrator that will allow you to check a certain mode and have the locking effected...

I have an include file on all my pages that does a check for the session variable and if it is not found redirects the user back to the login page.  I'm thinking that is where the system is sending people back out of the system but that means that the session variables either expire or are lost somehow.

Anyone had any similar experience with premature timeouts?  Thanks for any help or suggestions!

Tim
0
Comment
Question by:Ike23
  • 10
  • 8
  • 6
  • +2
27 Comments
 
LVL 17

Expert Comment

by:Tacobell777
ID: 12203668
The only thing I can think of that would do this is when the cf server restarts, or some code kills the session.

Have a look in your log files and make sure the cf server is not restarting itself...
0
 
LVL 4

Author Comment

by:Ike23
ID: 12203706
Sorry if this is a stupid question but where would I find the log files?  Do the logs automatically create themselves or do I have to turn them on in the CF Admin?  Why would the server restart itself?  Wouldn't that kill everyone's session at the same time?  This just happens to individuals so I doubt it could be a whole server restart.
0
 
LVL 35

Expert Comment

by:mrichmon
ID: 12203825
Assuming default install of CFMX

C:\CFusionMX\Logs

As for the questions


-What would cause an application to suddenly timeout before the session variable should timeout or what would cause a session variable to timeout before the value set in the cfapplication page?

Poor coding such as memory leaks or infinite loops, etc

-Could it be an issue with locking session variables?  

Yes

-Is there a quick way to check for unlocked session variables or a way to lock all session variables?

I don't know of one other than a find/search of your code for "Session"
0
 
LVL 35

Expert Comment

by:mrichmon
ID: 12203828
Oh I didn't see the CF 5 comment - but the log location should be similar....
0
 
LVL 17

Expert Comment

by:Tacobell777
ID: 12203832
true, if the cf server restarts it happens to everyone.
I would have a look anyway, you can look at the cf logs or the event viewer, for cf logs go into the admin and find them, for event viewer just go to administrative tools event viewer
0
 
LVL 9

Expert Comment

by:digicidal
ID: 12205209
Agreed with above, however one additional question:

Do you use any code to actively kill the session that is called automatically by either a scheduled event or a link?  (i.e. in your 'logoff' script).  Are you completely sure that this script cannot be called from any other location or process - I've worked with someone else's code that 'autotriggered' the destruction of the session structure if a timestamp was beyond a designated CreateTimeSpan() value - so even when the server saw the session as still valid the code would 'clean up' after this supposedly timed-out user.

The other thing to check if the CF logs don't show anything is to check in your server's event viewer to see if there were any memory events (overflows) or if the service force a restart due to an exception of some kind...  The only other thing that might also cause this - but might not be apparent to the user right away is if it boots them after a particular function is performed (or group of functions).  Pretty hard to guess on this one without knowing what your application does, how it's structured, and what the Servers hardware disposition might be (flaky memory, other apps mem leaks, disk write errors, etc.).  If nothing has changed in the CF server software, and nothing has changed in your code - it's most likely something has changed about the hardware or other software running on that server.
0
 
LVL 9

Expert Comment

by:digicidal
ID: 12205213
OK. A few more than 'one additional question' :)
0
 
LVL 2

Expert Comment

by:dldeeds
ID: 12212231
Maybe you have thought of this, but I did not see it mentioned. Do you have multiple cfapplication.cfm files that might have different time out lengths?
0
 
LVL 4

Author Comment

by:Ike23
ID: 12218280
Here's my cfapplication page:

<!--- Global Security Setings --->
<cfapplication
      name="intraNetApp"
      clientmanagement="Yes"
      sessionmanagement="Yes"
      setclientcookies="no"
      sessiontimeout=#sessionvariabletimeout#
      applicationtimeout=#CreateTimeSpan(1,0,0,0)#
      setdomaincookies="no"
>
<!--- IF THE LOGOUT BUTTON IS PUSHED THEN CLEAR THE SESSION VARIABLES AND DELETE THE COOKIES --->
<cfif isdefined("logout")>

<cflock scope="SESSION" type="EXCLUSIVE" timeout="10">
      <cfset structclear(session)>
   <CFCOOKIE NAME="CFID" VALUE="#CFID#" EXPIRES="NOW">
   <CFCOOKIE NAME="CFTOKEN" VALUE="#CFTOKEN#" EXPIRES="NOW">
</cflock>

<cfelse>

<!--- THIS WILL CHECK FOR PERSISTENT COOKIES AND DELETE THEM --->
<cfif (isdefined("Cookie.CFID")) AND (isdefined("Client.LastVisit"))>
  <cfset min_date = #DateAdd('H', -12, Now())#>
  <cfif DateCompare(Client.LastVisit, min_date) IS -1>
    <cfcookie name="CFID" value="#CFID#" expires="NOW">
    <cfcookie name="CFTOKEN" value="#CFTOKEN#" expires="NOW">
  </cfif>
</cfif>

<!--- THIS WILL SET A SESSION COOKIE IF ONE DOESN'T EXIST --->
<CFIF NOT IsDefined("CFID")>
   <CFLOCK SCOPE="SESSION" TYPE="READONLY" TIMEOUT="5">
   <CFCOOKIE NAME="CFID" VALUE="#SESSION.CFID#">
   <CFCOOKIE NAME="CFTOKEN" VALUE="#SESSION.CFTOKEN#">
</CFLOCK>
</CFIF>

<!--- THIS WILL CAUSE THE COOKIE TO EXPIRE ONCE THE BROWSER IS CLOSED --->
   <CFCOOKIE NAME="CFID" VALUE="#CLIENT.CFID#">
   <CFCOOKIE NAME="CFTOKEN" VALUE="#CLIENT.CFTOKEN#">

</cfif>

See anything wrong with the code?

I also have a include file that I put at the top of each page to check for the existence of a session variable to prevent direct browsing to pages within the application (code below):

Security include file:

<cfif isdefined("session.userid") and session.userid neq "">

<cflock timeout="10" type="EXCLUSIVE" scope="SESSION">
     <cfset request.userid = session.userid>
       <cfset request.wgid = session.workgroupid>
</cflock>

<cfelse>

<cflocation url="login.cfm" addtoken="no">

</cfif>      


Also, what do you mean by "leaks".  If I restarted my server would that clean up and leaks and make the system more stable again?  Thanks for any feedback.  This problem is one of those that could have multiple causes so any thoughts are welcomed.
0
 
LVL 35

Expert Comment

by:mrichmon
ID: 12221811
"leaks" would be not using CFLOCK when accessing session variables - with CF 5 you should lock READS and writes, with CFMX you can get away with only writes, but best practice is still to lock both
0
 
LVL 4

Author Comment

by:Ike23
ID: 12221883
Would that cause a session to end?  If a session variable was not locked would that mean that someone else could somehow switch values with another person?  I did a bunch of work locking my variables and reading on why to use them but I still haven't grasped why to lock variables other than "you are supposed to".  Would not locking a session variable within a custom tag cause any problems?  Thanks for your help...this problem has been confusing me for months.
0
 
LVL 35

Expert Comment

by:mrichmon
ID: 12221958
Not lockig (especially on versions prior to MX) can cause memory leaks.  Memory leaks can cause all sorts of random problems - including serious ones like taking down/crashing your entire server.

Not locking properly means that two threads of code could be attempting to write to the same place at the same  time.  It also means that one thread could be writing to the variable and another reads the data before it is completely written.  This can cause corruption of the server and the program.

Yes not locking within a custom tag could cause a problem.

I don't know if this is causing your problem of the session ending, but it is possible if the session is getting corrupt that it is being abandoned by the server.
0
 
LVL 4

Author Comment

by:Ike23
ID: 12221994
Just to be clear...  I guess I should do a search for "session." and then put code like this around each time a session variable is set or read right?  I do set my session.userid to the request scope in my include file so that I can reference that on some pages.  Would that cause any problems?
0
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 35

Expert Comment

by:mrichmon
ID: 12222016
It is so hard to say....

But with CF 5 not locking even reads such as :

<cfif isdefined("session.userid") and session.userid neq "">

has been known to crash systems....
0
 
LVL 4

Author Comment

by:Ike23
ID: 12222110
So I need to lock around my <cfif> statements?  That is something I don't think that I am doing.  What if there is a ton of code between the <cfif isdefined("session.userid")> will that cause any problems?  I'm starting to think that the locking is probably the problem since it is starting to happen now that I have more concurrent users.
0
 
LVL 9

Expert Comment

by:digicidal
ID: 12222168
If you do a great deal of work in a conditional just check at the beginning of the script and set a local variable to the state... example:

<cflock scope="session" type="readonly" timeout="10">
<cfscript>
if (isDefined('session.variable')) {
      varUserHasSession = 1;
      } else {
      varUserHasSession = 0;
}
</cfscript>
</cflock>

Now you can just proceed by checking whether or not varUserHasSession = 1 for the rest of the page.

Yes you can just use a <cfparam variable="varUserHasSession" default="0">
And then a <cfif> tag to set the value to 1 if session.variable is defined... but if you don't need to use other tags, putting your conditional statements in a <cfscript> tag has been shown to reduce the processing time required.

Either way works fine.
As another solution... if you have the money for the upgrade, why not use this as a good reason to upgrade to CFMX 6.1 -  then you won't have to lock any of your session reads... just some writes (although I haven't ever had any problems with not locking session vars in MX 6.1 - just Application vars.  It's always good practice tho to lock any variables that may have more than one simultaneous access possible no matter what their scope (or what language you are developing in for that matter).
0
 
LVL 4

Author Comment

by:Ike23
ID: 12222202
I'm afraid of upgrading to 6.1 since this is an intranet application that everyone in my company uses daily.  I guess I could try and upgrade on a test server and then see if that works first.  That sounds like the best plan though since I wouldn't have to worry about session locking.  Now you brought up a new point that makes me worry...  Why would I need to lock application variables?  What if I am using a few application variables like application.datasource?  Since the value is always the same for every call to that variable what is the harm in not locking it?
0
 
LVL 9

Expert Comment

by:digicidal
ID: 12222303
Side note - I added the unnecessary (in my example) timeout argument to the lock.  You need this if the lock is exclusive, but it is optional with read-only because your script essentially is working with a snapshot of the variable in this mode.  If another script updates a value in the variable your code inside the block will not be updated, but you will still be able to check any values for their state at the time the lock was instantiated.  If you make an exclusive lock you must declare a timeout value for the script that is as short as possible without the possibility of it timing out prior to your code fully executing.
0
 
LVL 4

Author Comment

by:Ike23
ID: 12222351
I remember setting the timeout to something like 20 or 30.  Is that bad?  Would that cause the app server to restart if it was set to restart in 10 seconds?  Thanks again for letting me pick your brain.  No one on the CF Forums has been as helpful in clearing up what I should actually do with locks and why I should do it.  So do I really need to lock application variables?
0
 
LVL 9

Accepted Solution

by:
digicidal earned 250 total points
ID: 12222352
application and session variables are STRUCTURES... so if something else writes to say application.SomeVar at precisely the same moment that something else writes to application.SomeOtherVar it can cause corruption - since the actual variable is just 'APPLICATION' -  the other parts are keys with can store other variables, arrays, structures, or values.

It's a good idea to read up on the APPLICATION and SESSION variables in the documentation.

Look here:
http://www.macromedia.com/support/coldfusion/ts/documents/tn17882.htm

It will tell you all you need to know, but here is a snippet that best describes the problems:

Why Does Shared Scope Variable Access Need to Be Locked?
Because ColdFusion Server uses multiple threads (multithreading), it is able to simultaneously work on requests from multiple users at the same time. It is also able to work on multiple requests from the same user at the same time. This can happen with a Web site that utilizes frames, when a user clicks the reload button on her browser before the initial request has completed, or when a user has multiple browser windows open.

Since these threads can access the same variables in memory at the same time, we are presented with the problem of the threads competing for the same resource. This competition normally leads to memory corruption. Corruption occurs because of the way the data is structured in memory and the changes that take place in these structures when the variables are altered. If one thread modifies the shared scope variable while another thread attempts to read the value of the variable, for example, memory corruption may result. Because the read and write are happening concurrently, the read may try to access the structure in a way that would be invalid after the write to the variable modified the data structure. Accessing memory in an invalid way, such as requesting the contents of a physical piece of memory that doesn't exist, causes memory corruption and process crashes.

In addition, if the data structures that track memory allocation become corrupted, the allocator will work incorrectly and large amounts of memory can "leak." Memory corruption also leads to crashes and/or server instability. Some of the symptoms of memory corruption follow:

ColdFusion PCode errors
cfserver process crashing/stopping/restarting
Unexpected shared scope variable evaluation results
Large growth in the amount of memory used by the cfserver process
Operating system instability
Locking variables prevent these problems by only allowing one thread to access the shared scope variable at a time. All of the other threads must wait in line to access the shared variables until the previous thread completes its action. In effect, access to the locked piece of code is single threaded.

0
 
LVL 9

Expert Comment

by:digicidal
ID: 12222439
No that is not a problem... actually I just reread the section in the docs and the timeout is not for the lock itself... my bad... its the time a function will wait to ATTAIN the lock... so setting this to 30 or even 90 is not a problem... the affected code will simply wait longer to set the lock... once the lock is instantiated all code will execute no matter how long it takes... See I learned something today about cflock too. :)  And yes, even with MX 6.1 you should lock any shared scope variables for writing at the very least.  Most reads can occur fine because they happen so quickly and do not actually modify the variable itself.  However with application variable you should really lock both reads and writes since multiple sessions may be writing to or reading from the variable.  With sessions, you need to lock in versions prior to MX, but there is much less chance of corruption because only that user can modify their own session - so unless your code executes two calls which overlap you should be fine.

The real answer tho is this: a lock requires almost nothing in processing time and is invisible to the user - a memory leak may cause your application to fail entirely (and in really bad cases the whole server itself) - and is DEFINITELY visible to the user.  If in no other way than it will slowly degrade the performance of the server, but usually because it will cause intermittent errors and strange behavior that the user doesn't expect.
0
 
LVL 4

Author Comment

by:Ike23
ID: 12222515
I still don't see why to lock application reads since they are all the same value but I'll take your word for it.  I guess it's time for me to do a site search for session and set up a test server so I can upgrade to 6.1.  Thanks for your help.

Tim
0
 
LVL 35

Expert Comment

by:mrichmon
ID: 12222535
The reason to lock reads is that someone else COULD be doing a write while the read is happening.

The read lock tells someone trying to write to wait until the read completes so taht they don't read partially written data.

Also the readlock will be postponed if the variable is being written....
0
 
LVL 9

Expert Comment

by:digicidal
ID: 12222567
If it's going to take a long time to retrofit your application to a well-formed state (using the locks) if you look halfway down the page I gave you a link for there is an option to have the server automatically check for and lock any unlocked shared scope variables.  The cost is server precompilation performance, but you can check that feature while re-tooling your code to minimize any effect of unlocked code first.  Just make sure to go back and uncheck it once you have all your locks in place to return the lost server cycles to other functions.

Good luck!
0
 
LVL 4

Author Comment

by:Ike23
ID: 12222614
Is that in the CF Administrator?  What option would you suggest?  I think that would be a good idea for now unless it makes the application so slow it is unusable...
0
 
LVL 4

Author Comment

by:Ike23
ID: 12232755
I checked the box that says "Sinlge threaded sessions" in the CF Administrator.  It almost seems like the application is working faster now.  From the description I think that this will at least prevent memory leaks for now until I can upgrade.
0
 
LVL 9

Expert Comment

by:digicidal
ID: 12234530
Yes, that is correct... by making your sessions single threaded it is basically forcing everything to be locked - so in a sense locks aren't needed... however, if you think it's faster now... just wait until you have your locks in and can once again let it handle multiple actions at once - safely for once!  Glad that helped.
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

When it comes to showing a 404 error page to your visitors, you do not want that generic page to show, and you especially do not want your hosting provider’s ad error page to show either. In this article, I will show you how to enable the custom 40…
Meet the world's only “Transparent Cloud™” from Superb Internet Corporation. Now, you can experience firsthand a cloud platform that consistently outperforms Amazon Web Services (AWS), IBM’s Softlayer, and Microsoft’s Azure when it comes to CPU and …
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now