Python 7.0pl5 Benutzerhandbuch

Seite von 124
Remote Access
116
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
self.joinGroup("database-services")
self._database = MySQLdb.connect(**kw)
self._cursors = 0
self.exportMethod(self.cursor)
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-