If you use WebSessionContext in your Xojo web projects, you’re probably aware by now that they’re not working very well. I thought I’d take a few minutes to tell you what’s going on and how we’re planning to fix it.
What is a WebSessionContext anyway?
First of all, a quick description of what WebSessionContext is supposed to do for you. WebSessionContext is a mechanism for accessing a particular existing WebSession from within an area of your application that would otherwise not know where it belongs. These include Threads, Timers, System Events, App Events, etc. Normally you could tell because you would get a SessionNotAvailableException when trying to access a particular WebSession in your code.
The Original Bug
Some time this spring, a bug was reported where, depending on the timing of things, commands could be directed to the wrong session if you had more than one non-session based object running at a time (Threads, Timers, etc…). Essentially, if your code yielded time back to the application using App.SleepCurrentThread, Thread.Sleep() or App.DoEvents(), and another item created a new WebSessionContext, when the context switched back to the original item, you were not guaranteed to have the correct session unless you created a new WebSessionContext right away. This lead to some hard-to-find bugs and a lot of head scratching on our parts trying to figure out what was going on.
The New Bug
Fixing the original bug was easy…the offending code was simply removed. Unfortunately, it also created a situation where in many cases the global Session() method would return Nil. To be honest, we only use a WebSessionContext in one place in our framework (the Animator class), so we completely missed it.
Now What?
We’re feverishly working on fixes for the next release. Included in that release is a fix for this unfortunate bug. This time WebSessionContexts are stored and retrieved based on ThreadID, and the WebSession reference you pass in will be stored as a WeakRef (this fixes the last memory leak we are aware of). There will be behavior changes however:
- WebSessionContext objects depend on scope. Once your instance goes out of scope, so does the object, and further calls to Session will raise an exception. If you need it to persist, store it somewhere more permanent (like a Class Property).
- Creating a WebSessionContext from within a valid WebSession will result in no Session change, even if you passed in another WebSession.
- If the passed WebSession is destroyed (if, for example, the user disconnects and the session goes out of scope), you will still get a SessionNotAvailableException. Make sure your code is set up to handle this situation.
While You’re Waiting…
If you need a solution right now, the best thing you can do is to store a Weak Reference to the WebPage that you need to update right in the object you are trying to reference it from. For instance, make a property on a Thread class and call it currentPage and assign it in the constructor. Whenever you need to update something on that page, type currentPage instead of WebPage1 and 95% of what you’re trying to do will work just fine.
Update: This issue was fixed in Xojo 2013 Release 2.