I have a web app deployed using Apache/CGI on CentOS. As of the last two Xojo releases, I have noticed some Websessions not quitting. I’d like some advice on how to troubleshoot this, but first some notes:
- I don’t think this problem was happening with Xojo R2, but I’m not sure exactly which release it’s started with.
- When a session doesn’t quit, all subsequent sessions also fail to quit.
- I have implement the session timeout (10 mins) event. When I use session.quit in code, I preceed it with a showurl command to change to a pure HTML page (handled by Apache, i.e., not a Xojo webpage).
- I have a monitoring app which lists the open sessions. I implemented a “kill” button that in the past allowed me to select a session and issue a “quit” command. This works fine until I encounter the session hang issue, after which I cannot kill any sessions manually. However, when I issues a manual quit to the monitoring session itself, the browswer shows the “gone offline” page, but when I refresh the page, the list shows a new monitoring session (as expected), but the previous session is still listed (i.e., it doesn’t actually quit).
- My only recourse now to recover memory is to occasionally kill the entire app using the Linux Killall command.
Is anyone else seeing this issue?
Any chance you have circular references going? Maybe a reference to a Session in a WebPage or a control? If you keep any, they should be WeakRefs.
Thanks Brad. That’s a good point and I’ll review my code. Perhaps I inadvertantly created a circular reference.
I checked and I don’t have any circular references in my code. What’s strange is that before the problem starts, I can force quit sessions from my “monitor” screen, but after it starts I can’t force quit any session at all (the browser loses the connection but the session remains).
Remember: Sessions don’t die immediately. They’ll linger for up to 3 minutes, and then memory will actually get released when garbage collection is done.
You said that you’ve set the session timeout to 10 minutes, this is merely a mechanism to allow you to notify users that they have been away for a period of time with no activity. It has no bearing on session behavior unless you implement Session.TimedOut.
Could it be that it’s your monitoring system that’s holding onto session references? Can you tell me more about how it retrieves the list?
I know that sessions linger for a while before disappearing. The difference I am seeing is that initially, the session list stays relatively clear as session “die out”, either through the clients closing/leaving the browser page or timeouts (my code switched to an html page and issues a session.quit), or me force quitting the sessions using the monitoring page. But when I come back, say, half a day later, I may find the session list full of old sessions and the session force quit doesn’t work anymore. If I then create new sessions they do not disappear, regardless of whether I close the webpage, issues a session quit, or let it timeout.
Anyway, yesterday I recompiled using RB2012R2.1 and since then the problem has gone away. (I was going to try 2013r3.1 but I couldn’t get hold of it in time.) As I mentioned before, the problem only appeared after I recompiled using 2013r3.2.
When I force quit a session, I call the session’s method using App.SessionWithIdentifier(id, ip).Quitforced, where “Quitforced” is
Here is the method that polls the sessions. It uses some other functions (not shown) to translate the returned numeric codes to understandable text.
Dim ip As String
Dim currentPageTitle As String
Dim starttime As String
Dim lastlogtime As String
Dim lastlogmsg As String
Dim sessuseragent As String
Dim browser As String
Dim platform As String
Dim renderingengine As String
Dim identifier as String
Dim SessionCount As Integer = App.SessionCount - 1
For i As Integer = SessionCount DownTo 0
ip = App.SessionAtIndex(i).RemoteAddress
ip = "error"
currentPageTitle = App.SessionAtIndex(i).CurrentPage.Title
currentPageTitle = "error"
starttime = App.SessionAtIndex(i).sessionStartTime.sqldatetime
starttime = "error"
lastlogtime = App.SessionAtIndex(i).lastLogTime
lastlogtime = "error"
lastlogmsg = App.SessionAtIndex(i).lastLogMessage
lastlogmsg = "error"
sessuseragent = App.SessionAtIndex(i).Header("User-Agent")
sessuseragent = "error"
browser = returnBrowser(App.SessionAtIndex(i).Browser)
browser = "error"
platform = returnPlatform(App.SessionAtIndex(i).Platform)
platform = "error"
renderingengine = returnRenderingEngine(App.SessionAtIndex(i).RenderingEngine)
renderingengine = "error"
listboxMonitor.AddRow ip, currentPageTitle, starttime, lastlogtime, lastlogmsg, sessuseragent, browser, platform, renderingengine
listboxMonitor.AddRow "error addrow"
identifier = App.SessionAtIndex(i).Identifier
identifier = ""
listboxMonitor.RowTag(listboxMonitor.RowCount-1) = identifier
I appreciate any help toward finding a solution. Thanks.
To help track this down, see what happens if instead of reporting each session, you just report the number of sessions, app.SessionCount. I wonder if accessing the session might be resetting its timeout counter, or something similar.
If just getting the count causes all sessions to close, then see what happens if you only refresh the session list every 10 minutes or so.
It would be very helpful if you could try it with 3.1. If you have a license, you can get it by logging into your account, going to the Downloads section and then clicking on Archived Versions.
I have another web app that runs on the same server and that one simply shows the app.sessioncount on the log in screen - it has no monitoring page. That one also showed runaway session counts after compiling with r3.2 and I’ve gone back to 2012r2.1. I should add, that with the original app, there have been instances when I have issued a killall command on the server and not used the monitoring page until much later, at which point it was already showing a long list of zombie sessions. The above two reasons are why I don’t think it is an issue caused directly by the monitoring page.
Greg, I’ll try with 3.1 and report back.
Same problem with Xojo 2013r3.1.
I’d like to try the earlier releases, but for some reason my account download page only shows me 2012r2.1 and earlier (I renewed in June 2013 just after Xojo was released). Customer support gave me a link to 3.1, but I don’t have 3, 2 or r1,
This thread has me looking at a WE App that has had memory issues. I found I was referencing the session from other windows and controls. Tried to figure out WeakRefs and added code similar to below where ever there was a reference to a session in a control or webpage. The following is an example in the shown event on a webpage. I have no idea if this the way to handle what is being referred to above but I still have open sessions accumulating.
dim ref as new weakref(session)
if session(ref.value).banner <> nil then
I fixed all other external session references in the same manner. My app still increments sessions without closing old ones either when folks time out and are referred to a external timeout page or just close their browser.
Currently using 2013r3.3
If you’re dimming a local variable, there is no need to use a weakref. The reference will go away as soon as the method returns.
I’m giving up on this for now - I can’t distil the issue to the point where I could raise a bug report. I’ve pulled my webapp apart into separate simpler components, removed as much code from the session open even (in case that was causing it), double-checked that I’m not holding any session references, etc. The fact of the matter is, 2012r2.1 works fine, but compiling the same code with Xojo2013r3.2 and 3.3 leads to sessions not closing at some point of time (works fine initially). I can’t test with r3.0 and r3.1 because they don’t appear in my account (I told Customer Support some time back about this).
For those with more time and expertise, running a CGI webapp on Linux (CentOS) under Apache, if you see what looks like a memory leak, please do me a favour and add in some code to check your open sessions. The symptoms of the problem will be that, at some point of time after starting the webapp, all new sessions will subsequently fail to close for any reason, and even a session.quit won’t work (although the client will see the “lost connection” page).
I wonder if the issue is something obscure like client’s having the wrong version of the framework (2012 vs. Xojo 2013) cached in their browser, and the interaction is what causes the issue. Wild guessing.
Did you ever solve this problem from over two years ago?
Currently they seem to be running fine - I’m not seeing any sessions lingering on even after months of continuous running.
I’m currently building my web apps with Xojo 2015r2.4, and they are running as standalone on CentOS servers with Nginx.
I recall getting a vague impression (but no real evidence to prove) that:
- The issue only happens with some releases of Xojo and not others;
- When it happens, it may be first triggered by some session error (user triggers a framework error, say) and, from then on, sessions fail to go away.
Sorry I can’t be of more help.
Thanks, Patrick. If you upgrade to Xojo 2016r1.1 and test, let us know.
So far, with Xojo 2016r1.1, I seem to have solved my “sessions not quitting” by never using Session.Quit.
Until this point, what I found was that after a while, when a Session.Quit failed to reduce Session Count (even after waiting an hour so), all subsequent Session.Quit events on various sessions would fail to reduce Session Count. At that point, the only way to get back to normal was to stop and restart the app.
I have now found that if I don’t use Session.Quit anywhere at all, this problem goes away. I now just let sessions die naturally with whatever timeout logic is built into the framework, or die a few minutes after the user closes the browser window. Now, invariably, when a session closes, Session Count eventually decreases.
I uploaded a simple app that reproduces this: Feedback 44360
I have unusual problem with session.Quit.
Code is very simple. I do have identifier of a remote session to be killed.
Dim ThisSession As WebSession
’ Get the session
ThisSession = App.SessionWithIdentifier(SesstionID)
' Force Quit
ThisSession = nil
But for some reasons it is NOT doing the job. Is there a IE11 setting that maybe prevents sessions to be killed?
No. But quitting sessions is dependent on other things:
- Quit doesn’t happen immediately. It sets a flag on the session so that the next time the cleanup routine runs, it will be told to quit. This routine is a low-priority thread, so depending on how busy your app is, it could take a while. I would not expect it to take longer than a minute though.
- WebSessions are very sensitive to leaks. If you’ve created any circular references in your code, the session can’t be destroyed.
A delicate problem is - it quits the session when debugging. It also quits on SOME computers, and it does not quit on others (typically these non-quit are IE 11, not sure if they use other browsers). So I must rule out possibility that error is in circular reference of the app, because it happens on specific computers (I do repeat exactly the same actions, very elementary such as: log in, do noting, log out). If I log in remotely from home to site, session is quitting (all browsers). If I use their local network to try to do the same - session remains forever.
That is why I was thinking that there might be some setting for IE11 (or computer setting/policy) that does that.