
Remote Access
Managing User Sessions
A common practice with web based services is to have a request initiate a unique session for a user. Having opened the session, any requests will then be identified with that session, with information re- garding the session potentially being cached on the server side until the session is closed. Such a ses- sion might also be used as a way of allocating a server side resource to that user, or creating a database cursor dedicated to a particular user so more complex queries can be made.
A scheme suitable for use over the service agent framework was previously described, however that implementation was based on the ability to subscribe to the existence of the owner of the session, with the session being automatically closed when the owner was destroyed. When the RPC gateway is used, this approach can’t be used, as the sender of the request will be a transient service created by the RPC gateway to service just that request. An alternative when the RPC gateway is being used is to automat- ically close the session after a set period of inactivity.
class Database(netsvc.Service):
def __init__(self,name="database",**kw): netsvc.Service.__init__(self,name) self._name = name
def executeMethod(self,name,method,params): try:
return netsvc.Service.executeMethod(self,name,method,params) except MySQLdb.ProgrammingError,exception:
self.abortResponse(1,"Programming Error","db",str(exception)) except MySQLdb.Error,(error,description):
self.abortResponse(error,description,"mysql") def cursor(self,timeout=60):
self._cursors = self._cursors + 1
name = "%s/%d" % (self._name,self._cursors) cursor = self._database.cursor() Cursor(name,cursor,timeout)
child = "%d" % self._cursors return child
The idea is that when a request is made, a unique instance of a service is created specific to the session, with a name which is then passed back to the remote client. In the example shown, if the service was originally accessible using the URL "http://localhost/database", the instance of a service created for that specific session would be the same URL but with the session id appended, separated by "/". Eg., "http://localhost/database/1". Obviously, a session id which could not be easily guessed should however be used.
The client would now direct all future requests to the new URL. When the client has finished with the service it would call the "close()" method on the service. If for some reason the client did not ex-
116