[Web-SIG] and now for something completely different!
Ian Bicking
ianb at colorstudy.com
Tue Aug 16 18:54:45 CEST 2005
mike bayer wrote:
> - because a "read" operation also registers a "last accessed time" data
> member, its not using multiple reader/single writer style locking,
> everyone is a writer. However, since I am sensitive to iframes, ajax
> calls, and dynamic image calls hitting the same session concurrently
> within a request which I'd rather not slow down, I do something less than
> optimal which is I open the session store and read the full thing into
> memory first when its accessed, and then immediately unlock. This
> obviously can create problems for an application that is storing huge
> amounts of data in its session which is not required in full for any one
> request.
I think we can all agree that we're not expecting sessions to be primary
storage for large objects, so we shouldn't worry too much about this.
However, as a use case for objects derived from the session, consider an
upload form with validation. If someone uploads a large file but has an
invalid form, you might want to keep the file around on the server side.
You can't put it in the form (hidden or not) because then you
needlessly retransfer the file twice. You can't leave the filename in
the input field, because browsers don't allow that.
So in a lot of ways this is where it would be nice to put a big file in
the session. But you should really put it in a temporary directory and
put the filename in the session (you could put the filename in a signed
field in the form, but ignore that for now). The advantage of putting
it in the session is that the session has tracking, a timeout, etc.
So with the API I gave you might do:
session['upload_filename'] = '/tmp/foo.jpg'
session.store.expire_session_callbacks.append(delete_upload_filename)
def delete_upload_filename(session_id):
session = session_store.load_session_read_only(session_id)
if 'upload_filename' in session:
filename = session['upload_filename']
if os.path.exists(filename):
os.unlink(filename)
Though there's a couple issues. The sessino store should be passed
along with the session ID. It should be specified that loading a
session from this callback will not cancel its expiration. Maybe
per-session callbacks should be allowed; in which case the callbacks
would have to be identifiable by a string or some pickleable value,
since you can't pickle the functions themselves. I suppose you could
implement the callback as an instance with a __call__ method, which
pickle turns into a class name plus __dict__ values. I hate overusing
__call__; if it has to be an instance (to be pickleable), then might as
well give it a method name, and maybe call other methods as well. Then
it essentially becomes an ad hoc event system.
--
Ian Bicking / ianb at colorstudy.com / http://blog.ianbicking.org
More information about the Web-SIG
mailing list