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? > > 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

