App worked in 2012R2.1 but not XOJO

Greg - I wanted to go back to this line and point out that the Feedback project is only intended to focus on and illustrate the WebSessionContext bug. It’s intended for a single user/page load. Re-reading this thread I think perhaps you’re focusing on what I did to setup the test rather then the test. If that’s the case I could delete my first reply as I was misunderstanding you, though the second is still relevant.

Yes, I realize that multiple users would result in App.MySession getting repeatedly set. That’s not the point and not relevant at all to what Dean discovered. I just needed to get a session…any session…into an app property to setup the test.

[quote]Dim objContext As New WebSessionContext(Self.MySession)
Dim objSession As WebSession = Session 'Fine in 2012r2.1, NIL in Xojo.[/quote]

These are the only two lines that matter. Assuming Self.MySession is not NIL, then why would Session return NIL in the very next line?

Okay, so I based all of my assumptions on the example project you supplied, which is a little flawed because it doesn’t show a real-world scenario. It would have been extremely helpful if you’d put some comments in there.

Now that I am able to see what you’re trying to do, maybe I can get to the bottom of this.

I apologize Greg. That was my bad. I feel frantic and rushed today, so I just whipped it together and uploaded it ASAP.

Okay. The reason this code was removed was because we were looping through the list of contexts and returning the Session object associated with the last context created regardless of where it came from. While that will work fine in an app that has one user, in a threaded environment, you only have a 50% chance of being right with two, 33% with 3, 25% with 4 (you get the picture).

I’ll discuss this with Thom and Geoff tomorrow, but it looks like we could revert this change and then make a version of the Session method that takes a WebSessionContext object which will look through the list of currently defined contexts and return the correct matching Session object. But it’s still going to require code changes on your part because it’s going to require adding the context object to your calls to Session.

I’m still not in favor of creating a scenario whereby the main thread might get associated with a particular Session. That will most likely end up creating lots of hard-to-find bugs in user projects.

I agree…

Forgive me because I know we keep going around about this. But why isn’t this as simple as…

WebSessionContext - put IDs for the thread and session into a table.
Session - look up the thread ID in the table and return the session (or NIL if it’s not there).
Cleanup - when the context or the thread go out of scope, or when WebSessionContext.Stop is called, remove that row from the table.

This would work for Thread as well and be immune to context switches.

Correct me if wrong, but if an event starts on the main thread, doesn’t that event have to complete before another one can start on the main thread?

So MainThread.HandleSpecialURL can context switch to other threads handling page events. But doesn’t it have to complete before HandleSpecialURL can start for a different browser connection? Or before, say, a Timer.Action can fire?

In that case there should be no problem associating the main thread with a session. When the event completes the context goes out of scope and the main thread is associated with nothing. You could even enforce this by explicitly clearing the row with the main thread from the table when the event exits. Just in case someone keeps the context in a more permanent location.

If people have to keep the context around, why not just keep the session around? The only reason this is coming up is because Session has been relied upon to provide the correct session regardless of the origin of the call stack. And WebSessionContext was…right or wrong…presumed to be the way to insure this starting from server side events. So there’s a lot of code that doesn’t pass the session around as a property or parameter.

If we have to start passing something around, we might as well pass the session itself.

[quote=10911:@Daniel Taylor]Correct me if wrong, but if an event starts on the main thread, doesn’t that event have to complete before another one can start on the main thread?

So MainThread.HandleSpecialURL can context switch to other threads handling page events. But doesn’t it have to complete before HandleSpecialURL can start for a different browser connection? Or before, say, a Timer.Action can fire?[/quote]

That’s not been my experience. If code running on the main thread has a loop in it, socket events will fire just fine.

[quote=10911:@Daniel Taylor]If people have to keep the context around, why not just keep the session around? The only reason this is coming up is because Session has been relied upon to provide the correct session regardless of the origin of the call stack. And WebSessionContext was…right or wrong…presumed to be the way to insure this starting from server side events. So there’s a lot of code that doesn’t pass the session around as a property or parameter.

If we have to start passing something around, we might as well pass the session itself.[/quote]

That’s what I’ve been advocating. But there is a flaw… and that is that there is another part of this mechanism that’s broken (you touched on this in one of your earlier posts). The idea of being able to say:

WebPage1.Button1.caption = "Hello World"

…from anywhere goes completely out the window. In fact you’d need to put:

mySession.WebPage1.Button1.caption = "Hello World"

which you can only do if mySession is of type Session as opposed to WebSession.

Yes. This is worrying. The sessions are at the heart of our applications. They must be very reliable, well insulated, and very fast. It’s already annoying that Thom said that calls the sessions are not fast.

(sorry for my bad english)

I know that’s come up, but whenever I’ve timed Session the speed has been fine, below 10 microseconds. I don’t think performance is an issue.

If i remember Thom said that calling

Dim session as Session = Session

prior to calling Session.

Edit: Previous post was a bit wrong. Edit?

If i remember correctly, Thom said that calling

Dim session as Session = Session

prior to calling Session would speed things up a bit. But 10 microseconds is quite fast :wink:

Really? And the code executes on the main thread? That throws a wrench into things. Tracking and setting up the correct session while jumping between event handlers on the main thread would likely be too much work. I suppose running socket events in their own threads on WE would be too much as well.

Is there always a thread associated with a session to handle page events? Would it be possible to let us schedule code to run on that thread, the same as if the code was triggered from a WebButton or WebTimer Action event?

Consider the WebSessionContext example in the docs. Could we have something like:

[code]Dim SessionCount As Integer = App.SessionCount

// Loop through all sessions and have them display a new
// ExceptionPage.
For i As Integer = 0 to SessionCount - 1
App.SessionAtIndex(i).Run AddressOf SomeDelegateMethodThatOpensANewExceptionPage
Next[/code]

That would probably be less disruptive to existing code then having to pass around a session or a context. All the examples I can think of in projects I’ve worked on where I’ve used WebSessionContext could be quickly reorganized if I could schedule some or all of the code to run on the session’s thread. WebSessionContext could disappear, and a session would never be associated with the main thread.

We use

For Count_Int32 As Int32 = 0 To App.SessionCount - 1 . . . App.SessionAtIndex(Count_Int32).My_Boolean = True Next

combined with a WebTimer that checks Session.My_Boolean to trigger WebPage events. It is simple and works very reliably.

[quote=11108:@Frederick Roller]We use

For Count_Int32 As Int32 = 0 To App.SessionCount - 1 . . . App.SessionAtIndex(Count_Int32).My_Boolean = True Next

combined with a WebTimer that checks Session.My_Boolean to trigger WebPage events. It is simple and works very reliably.[/quote]

That wouldn’t work for some of the use examples I can think of because of the delay and uncertainty introduced by the WebTimer.

MsgBox holds up the WebTimer but it has otherwise proven to be responsive for our needs. We set the Period to one second, which is frequent enough to update the various controls with any new or changed information.

If timing is critical then you could eliminate the WebTimer on each WebPage and do all the work from the calling method. You could also mix the two techniques. Or you might use another technique altogether. The upside is that you have choices.

Some of the use examples I can think of can’t necessarily tolerate the browser round trip.

??? Then you’re back on the main thread with no access to Session.

[quote=11415:@Daniel Taylor]Some of the use examples I can think of can’t necessarily tolerate the browser round trip.
??? Then you’re back on the main thread with no access to Session.[/quote]

If none of the suggestions in this conversation meet your needs then the design and/or tool may need to be reconsidered.

Frederick - have you read the whole thread? This is about the WebSessionContext function no longer working in some situations. It’s not a simple design consideration. Some tasks that are frequently performed in WE become difficult or impossible with the loss of this functionality.

Okay. We’ve had some internal discussions about this and the current behavior is definitely a bug. Unfortunately, in our attempts to fix the first problem, we’ve introduced a second one.

That being said, we are working on a fix for the next release.

Daniel, the approach I use in Studio Stable Web Essentials with “mySession” is to not ever have to use WebSessionContext. The approach has solved the basic problem over a few releases. See:

http://www.studiostable.com/webessentials/mysession