We've looked into the problem a bit deeper.. There is a problem but it's different than what was in the first post.
The problem seems to be in the locking of the session file: Two processes/requests open the same session file for write and thus get a handle on it One request gets the portalocker lock on the session file, the other one blocks and waits for the first request to release the lock. The first request writes the changes to the session file, and releases the lock. The second request then gets the lock, but still uses the old file handle and results in an EOFError exception The first patch improved the situation, because the file is re-opened after the file is released. However, a proper way to handle this would be to use a lock file, which is used only for locking and not for storing data at the same time, as per attached patch --- globals.py 2011-03-14 16:17:19.466604041 +0100 +++ globals.py_new 2011-03-11 16:55:33.000000000 +0100 @@ -269,10 +269,12 @@ response.session_id = None if response.session_id: try: + response.session_lock = \ + open(response.session_filename+'.lock', 'wb') + portalocker.lock(response.session_lock, + portalocker.LOCK_EX) response.session_file = \ open(response.session_filename, 'rb+') - portalocker.lock(response.session_file, - portalocker.LOCK_EX) self.update(cPickle.load(response.session_file)) response.session_file.seek(0) oc = response.session_filename.split('/') [-1].split('-')[0] @@ -395,21 +397,23 @@ session_folder = os.path.dirname(response.session_filename) if not os.path.exists(session_folder): os.mkdir(session_folder) + response.session_lock = open(response.session_filename +'.lock', 'wb') + portalocker.lock(response.session_lock, portalocker.LOCK_EX) response.session_file = open(response.session_filename, 'wb') - portalocker.lock(response.session_file, portalocker.LOCK_EX) if response.session_file: cPickle.dump(dict(self), response.session_file) response.session_file.truncate() try: - portalocker.unlock(response.session_file) + portalocker.unlock(response.session_lock) response.session_file.close() + del response.session_lock del response.session_file except: ### this should never happen but happens in Windows pass def _unlock(self, response): - if response and response.session_file: + if response and response.session_file and response.session_lock: try: - portalocker.unlock(response.session_file) + portalocker.unlock(response.session_lock) except: ### this should never happen but happens in Windows pass