You are right. Please check trunk again. Massimo
On Aug 27, 10:25 am, Jonathan Lundell <[email protected]> wrote: > On Aug 25, 2010, at 8:12 PM, Jonathan Lundell wrote: > > > > > On Aug 25, 2010, at 7:56 PM, mdipierro wrote: > > >> This is a bug. I fixed it in trunk. Thanks Jonathan. > > > It's fixed in the sense that it won't raise an exception. But now how is > > calling _unlock different from calling forget? > > Nag. > > > > >> On Aug 25, 9:30 pm, Jonathan Lundell <[email protected]> wrote: > >>> On Aug 25, 2010, at 6:37 PM, mdipierro wrote: > > >>>> The problem is only if have two http request from the same client in > >>>> the same session > > >>> Thanks for that; I was wondering under which conditions unlocking might > >>> be permissible (and I'm still not entirely clear, but never mind for now). > > >>> My concern is this. Here's unlock: > > >>> def _unlock(self, response): > >>> if response and response.session_file: > >>> try: > >>> portalocker.unlock(response.session_file) > >>> response.session_file.close() > >>> del response.session_file <<<<<------------------------- > >>> except: ### this should never happen but happens in Windows > >>> pass > > >>> Now we save the session file: > > >>> def _try_store_on_disk(self, request, response): > >>> if response._dbtable_and_field \ > >>> or not response.session_id \ > >>> or self._forget: > >>> self._unlock(response) > >>> return > >>> if response.session_new: > >>> # Tests if the session folder exists, if not, create it > >>> session_folder = os.path.dirname(response.session_filename) > >>> response.session_file = open(response.session_filename, 'wb') > >>> portalocker.lock(response.session_file, portalocker.LOCK_EX) > >>> cPickle.dump(dict(self), response.session_file) > >>> <<<<<<<<<---------------- > >>> self._unlock(response) > > >>> But response.session_file is None at this point. > > >>>> A arrives loads session and unlocks > >>>> B arrives loads session and unlocks > >>>> A change session and saves it > >>>> B changes session and saves it > > >>>> Nothing breaks but B never sees changes made by A and they are > >>>> overwritten by B. > >>>> With locks > > >>>> A arrives loads session > >>>> B arrives and waits > >>>> A change session and saves it > >>>> B loads session (with changes made by A) > >>>> B changes session and saves it > > >>>> On Aug 25, 3:52 pm, Jonathan Lundell <[email protected]> wrote: > >>>>> On Aug 25, 2010, at 1:41 PM, mdipierro wrote: > > >>>>>> call > > >>>>>> session._unlock() > > >>>>>> if you do not need session locking > > >>>>> If you do that (without calling session.forget), what will happen in > >>>>> _try_store_on_disk when cPickle.dump(dict(self), response.session_file) > >>>>> is called with a None file argument? Or is cPickle.dump cool with that? > >>>>> Or am I misreading the logic? > > >>>>>> On Aug 25, 11:38 am, Phyo Arkar <[email protected]> wrote: > >>>>>>> Yes may be session was locked , thats why > >>>>>>> session.current=processing_path not working > > >>>>>>> But then again , while processing files i try opening separate page , > >>>>>>> to other controller , it was waited till the first (file Crawler) page > >>>>>>> finished parsing. > > >>>>>>> ok i will make a separate thread about this. > > >>>>>>> On 8/25/10, mdipierro <[email protected]> wrote: > > >>>>>>>> On Aug 25, 11:00 am, Phyo Arkar <[email protected]> wrote: > >>>>>>>>> Did I Read that reading files inside controller will block web2py , > >>>>>>>>> Does > >>>>>>>>> it? > > >>>>>>>> No web2py does not block. web2py only locks sessions that means one > >>>>>>>> user cannot request two concurrent pages because there would be a > >>>>>>>> race > >>>>>>>> condition in saving sessions. Two user can request different pages > >>>>>>>> which open the same file unless the file is explicitly locked by your > >>>>>>>> code. > > >>>>>>>>> Thats a bad news.. i am doing a file crawler and while crawling , > >>>>>>>>> web2py is blocked even tho the process talke only 25% of 1 out of 4 > >>>>>>>>> CPUs .. > > >>>>>>>> Tell us more or I cannot help. > > >>>>>>>>> On 8/25/10, pierreth <[email protected]> wrote: > > >>>>>>>>>> I would appreciate a good reference to understand the concepts you > >>>>>>>>>> are > >>>>>>>>>> talking about. It is something new to me and I don't understand. > > >>>>>>>>>> On 25 août, 11:22, John Heenan <[email protected]> wrote: > >>>>>>>>>>> No, nothing that abstract. Using WSGI forces a new thread for each > >>>>>>>>>>> request. This is is a simple and inefficient brute force approach > >>>>>>>>>>> that > >>>>>>>>>>> really only suits the simplest Python applications and where only > >>>>>>>>>>> a > >>>>>>>>>>> small number of concurrent connection might be expected. > > >>>>>>>>>>> Any application that provides web services is going to OS block on > >>>>>>>>>>> file reading (and writing) and on database access. Using threads > >>>>>>>>>>> is a > >>>>>>>>>>> classic and easy way out that carries a lot of baggage. Windows > >>>>>>>>>>> has > >>>>>>>>>>> had a way out of this for years with its asynch (or event) > >>>>>>>>>>> notification set up through an OVERLAPPED structure. > > >>>>>>>>>>> Lightttpd makes use of efficient event notification schemes like > >>>>>>>>>>> kqueue and epoll. Apache only uses such schemes for listening and > >>>>>>>>>>> Keep- > >>>>>>>>>>> Alives. > > >>>>>>>>>>> No matter how careful one is with threads and processes there > >>>>>>>>>>> always > >>>>>>>>>>> appears to be unexpected gotchas. Python has a notorious example, > >>>>>>>>>>> the > >>>>>>>>>>> now fixed 'Beazly Effect' that affected the GIL. Also I don't > >>>>>>>>>>> think > >>>>>>>>>>> there is a single experienced Python user that trusts the GIL. > > >>>>>>>>>>> John Heenan

