durusmail: quixote-users: Session persistence for Quixote 2.0
Session persistence for Quixote 2.0
2005-05-26
2005-05-27
2005-05-27
2005-05-27
2005-05-27
2005-05-27
2005-05-27
2005-05-27
2005-05-28
2005-05-29
2005-05-29
2005-05-29
2005-05-28
2005-05-28
2005-05-29
2005-05-29
Sessions in mod_python (was [Quixote-users] Session persistence...
2005-05-29
Session persistence for Quixote 2.0
mso@oz.net
2005-05-27
Titus Brown wrote:
> I sat down and implemented simple persistent session stores for Durus,
> PostgreSQL, and shelve, as well as a simple directory/file based
> session store.
>       http://issola.caltech.edu/~t/transfer/qx-sessions.tar.gz

Hooray!

I ran test_session.py with MySQL (see below), Durus, shelve, and directory
storage, and didn't get any errors.  test_session.py is a Quixote
application with a number-incrementing link and login/logout links.
Because the store selector is hardcoded in create_publisher(), I had to
change it in the source between each run.  Observations:

- For MySQL, I modified SQLSessionStore.__init__ to take an already-open
connection from the caller.  This shrinks the method to two lines and
eliminates the module's dependency on psycopg.

- This code is so much more straightforward and flexible than the default
Quixote code I'd consider it a significant improvement.  It makes it easy
to define additional session stores in the future.

- directory_store.save_session() has an extra comma in the dump() call.

- Session.is_dirty() is apparently not used anywhere.  This means I don't
have to subclass Session anymore to use it with persistent stores?
Hooray.

- Session.has_info(), however, is used.  If it returns false but a session
exists, the session cookie is revoked with prejudice.

- NotImplementedError() is better than Exception("unimplemented"), as has
been pointed out.

- Since these classes are so small, why not put them all in one module?
They can import their pecular stuff in their methods, to avoid the module
depending on all libraries.

- Locking is a general problem; perhaps hooks belongs in the
PersistentSessionStore base class.  On the other hand, perhaps it's
semantically different for each store. DurusSessionStore and
ShelveSessionStore lock the whole table, so they don't need an argument.
DirectorySessionStore should be locking the file handle for the specific
session.  (But different platforms require different implementations, so
separate lock/unlock methods would be good.)

- SQLSessionStore hardcodes the SQL syntax in the middle of larger
methods.  While this syntax works for PostgreSQL and MySQL, it would be
more portable to have separate SQL-generation methods:

    def _load_session_sql(self):
        return "SELECT ..."

- SQLSessionStore also assumes the connection is transaction safe.  DB-API
says you cannot call conn.rollback() on an unsafe connection, yet the
method just calls it anyway.  It works in MySQLdb (although you may get an
"incomplete rollback" error sometimes).  I guess all the little SQL
databases (SQL lite, Gadfly) are transaction safe so maybe it doesn't
matter any more.  Do you really need to rollback at the beginning of each
method?    I read somewhere that the application should give us a separate
db connection unrelated to any other database operations in the
application.

- SQLSessionStore also assumes the .execute() substutions use "%(var)s"
syntax.  That would fail on some database systems.  But since it affects
the format of the argument (dict or tuple), perhaps we can't do much about
it, since the alternative would be to do the substitution ourselves and
have to deal with quoting.

- You can use SQL REPLACE to avoid the UPDATE/INSERT 'if'.



reply