The Google App Engine/J environment gives you access to the standard Java mechanism for handling HTTP-sessions - namely the familiar HttpSession (javax.servlet.http.HttpSession).
The first thing to note about the GAE/J HttpSession is that by default you're only allowed read-access to the session. If you want write to the session -- that is calling setAttribute(..., ...) -- you're required to setup session handling by adding <sessions-enabled>true</sessions-enabled> to your WEB-INF/appengine-web.xml.
Once you've enabled sessions you'll have HttpSession:s that behave like you're used to. Well, they behave like you're used to -- you can getAttribute(...) and you can setAttribute(..., ...) -- but behind behind the scenes there are a few implementation details to be aware of.
As described in a previous post two consecutive HTTP-requests sent by the same user to the same GAE/J-app may very well be served by two different JVM:s. An application developer would under normal circumstances assume that what he writes to the session in request N is available for retrieval from the session in request N+1 (assuming that the time between the two request is reasonably small). But in the case of GAE/J those two requests might be served by different JVM:s. Luckily, the GAE/J infrastructure makes sure that the session data is shared across all JVM:s serving your requests.
The sharing of HttpSession data is achieved by temporarily storing your session data in the App Engine Datastore and memcache
After your servlet has processed the request and returned its reponse a serialized version of the HttpSession is stored in the App Engine Datastore and memcache. If subsequent requests are routed to other JVM:s this data will be read to re-create the HttpSession.
A Datastore entity of kind "_ah_SESSION" is created for each new HttpSession. The entity key is "_ahs" + session.getId(). Each _ah_SESSION entity has two properties "_values" and "_expires".
The "_values" property is simply the serialized byte[] representation of a HashMap that includes the the session data.
The "_expires" property is the absolute time-to-live of the HttpSession and is expressed in milliseconds since January 1, 1970 (Unix time expressed in milli-seconds). The default time-to-live is 24 hours, but can be configured by altering . The _expires field is updated each time the session is active (_expires = System.currentTimeMillis() + 24 * 60 * 60 * 1,000 = System.currentTimeMillis() + 86,400,000).
Automatic removal of expired ah_SESSION entities (_ah_SESSION:s where _expires < System.currentTimeMillis()) did not make it to the initial GAE/J release, but it's probably safe to assume that it will be fixed in an upcoming release.
I'm planning a follow-up blog post about the corresponding loading and retrieval of HttpSession data from the memcache.
This is what I've found out about GAE/J session handling so far - please leave a comment if you have any additions and/or corrections!
10 comments: