On Apr 5, 2011, at 9:25 AM, David Warnock wrote: > Jonathan, > > > This policy is okay, but not good for reasons argued above. It is > > better not acquiring a lock unless you need one than to keeping a lock > > unless you don't need it. > > My question is: in your locking policy above, what's the purpose of locking > at all? > > I wonder whether it would be possible to have a strategy as follows: > > - default behaviour stays as now (for compatibility) > > - an additional decorator is added to specify that this method should be > called without locking the session > > To allow fine grained session control for long running methods maybe we could > have the following method added > - reload_session (to reload the session. If we have not locked the session > then it might have been changed by another process since we loaded it. This > will refresh our copy so the values are up-to-date. If another process has > the session locked then we will pause here until the lock is released. This > method should have an argument to control whether the session is locked when > it is reloaded so then we can safely modify the session knowing it is both > up-to-date and locked).
I've been trying to work out logic along those lines. A decorator would be difficult, because the locking happens very early in a request, and it'd be tricky to communicate from the decorator to the locker. But that's an implementation detail. An alternative would be to flag an entire application as taking responsibility for its own session logic. In that case, the request logic would not call session.connect at all, but leave it for the app to do first thing in its model. At that point, the controller and function have been determined, so the app can do whatever it wants to with the session. (This is already what happens, more or less, when sessions are kept in a database, as with GAE.) Then the app could implement several different request-dependent policies: 1. don't use the session at all: never read it, never lock it 2. read-only: read the session under a shared lock (to ensure atomicity) and immediately unlock 3. read-modify-write: same as existing logic, including a call to session.forget as soon as the write is complete 4. hybrid: start out read-only, but later switch to read-modify-write. This would require re-reading the session under the exclusive lock, which could be quite tricky depending on the app's logic (re-reading isn't tricky, but dealing with changes to the session data might be). As a case in point, session.flash is in effect a global variable shared by all the requests in a session. If requests in a session that use request.flash are not serialized, then the session.flash logic is going to break.

