Via Keith – here’s a problem I’m kicking myself for not covering explicitly in [email protected] – Troubles with Asynchronous Ajax Requests and PHP Sessions by Marc Wandschneider.
Normally, when you write web applications in PHP, this is really not an issue, as each page request gets their own execution environment, and a user is only visiting one page at a time. Each page request coming from a particular user arrives more or less sequentially and shares no data with other page requests.
Ajax changes all of this, however: suddenly, one page visit can result in a number of simultaneous requests to the server.
Now before I go any further – this is not a PHP problem despite the title (I hope the web ring is paying attention)- this is is a feature of HTTP – it’s stateless. The problem is really the blurring of lines AJAX introduces – this goes right to the line between the two kinds of AJAX – is the client or the server managing state?
As Keith points out;
In short, server-side technologies like PHP don’t let you lock access to your session across requests.
I’d broaden that a little – in short, using a stateless protocol like HTTP, any attempt to lock server side resources across requests will always be an ugly and potentially dangerous hack. For example, what if the client suffers a power cut, shortly after locking something?
As an aside, a useful case study is Dokuwiki, which implements a page locking mechanism to prevent issues with two people editing at the same time. It does this using a “lock” file which get’s “touched” with the latest timestamp whenever you begin editing a page or hit preview. If the server doesn’t hear from you for 15 minutes (default), your lock may be transferred to someone else. As it goes, it’s a pretty good implementation, as it will never result in “zombie” locks that require an administrator to clear – I don’t think there’s a better way to do it. But the timing is based on assumptions about a very specific task that end users are performing (editing a wiki page) and 15 minutes is clearly too long for the typical things people are doing with AJAX. I don’t think this approach can be translated to AJAX – it can’t be done in a generic manner.
Muddying the Waters
The conclusion Marc comes to is probably the smartest;
Now that we are aware of this problem and how it can manifest itself, the next question is, of course, how do we solve it? Unfortunately, I think this is one of those problems best solved by avoiding it. Building in logic and other things into our web application to lock the threads of execution (i.e. individual requests) would be prohibitively expensive and eliminate much of the fun and many of the benefits of asynchronous requests via Ajax. Instead, we will avoid modifying session data when we are executing multiple session requests.
Along with things I tried to raise here, this is then another thing you’ve got to watch out for when writing AJAX apps. It doesn’t have to be a problem – it depends on what you’re doing.
To try to place that is some kind of big picture, it’s something like “Hey our database doesn’t support ACID transactions but if you’re careful, it won’t matter”. Perhaps you can relate to how ridiculous that is – perhaps not (and yeah – I know – <insert well known DB here that didn’t do transactions once upon a time>) .
What’s troublesome is reading the type of responses to this problem, such as those in reply to AJAXian’s coverage of this. In particular the guys that should “get it” clearly don’t;
The thing about PHP is that it is request based, meaning that information storage is not persistent across requests. The session data is still saved/restored upon each request. If you cannot deal with this and need multiple asynchronous requests to a application to access the same dataset (why is beyond me, there’s other ways to code around that), then I suggest going to a J2EE platform.
Go back to Old Kent Road. Do not pass Go. The thing about HTTP is that it is request based – no matter how many EJBs you throw at it!
The problem here is really specific to the HTML++ style apps (Client / SOA, when / if it happens won’t suffer from this, the session being purely client side) – people really need to be aware that the initial ease of “Hello World!”@localhost doesn’t translate to AJAX == easy. I know AJAX enthusiasts don’t want to hear about the problems but with everyone reading from different sheets and others playing “Hear no evil, speak no evil, see no evil”, we’re not progressing the bar about what you can and can’t do with it. Turning that on it’s head, that AJAX is actually harder than it seems leads to a requirement for subject experts – see that as a good thing if you will.