From: Geoffrey T. <gta...@na...> - 2004-02-19 21:28:09
|
Matt Feifarek wrote: > On Thu, Feb 19, 2004 at 02:17:59PM -0500, Geoffrey Talvola wrote: >> It seems to me that as long as you're not storing ZODB-managed data >> IN the servlet instance somehow, this would cause no problems. > > We are keeping a reference to ZODB-managed data throughout > awake/sleep, but we always nullify it before sleep is done. (We set > all zodb and object references to None) When the servlet goes back to > the pool, it should have no references to any zodb stuff, unless zodb > is sneaking something in via some of its deep-magic plumbing. > > Thanks for the help. Aha. Exceptions can definitely cause sleep() to be skipped. If an exception happens during respond() or during awake() then sleep() does not get called. This smells like a bug to me. The code in question is in Application.py: try: self.awake(transaction) try: self.respond(transaction) except EndResponse: pass self.sleep(transaction) except EndResponse: pass Looking at this more closely, there ought to be a try/finally in there so that sleep() always gets called if awake() succeeds, something like: try: self.awake(transaction) try: self.respond(transaction) finally: self.sleep(transaction) except EndResponse: pass Or perhaps sleep should always get called even if there is an exception in awake(): try: try: self.awake(transaction) self.respond(transaction) finally: self.sleep(transaction) except EndResponse: pass - Geoff |
From: Geoffrey T. <gta...@na...> - 2004-02-19 23:19:56
|
Matt Feifarek wrote: > Geoffrey Talvola wrote: > >> Aha. Exceptions can definitely cause sleep() to be skipped. >> >> If an exception happens during respond() or during awake() then >> sleep() does not get called. This smells like a bug to me. >> >> > I always thought that this was funny. We wrap up the > EndResponse(s) that > we raise with a .cleanup() method (which is usually called > from sleep). > > SO, we're still cleaning up, even when EndResponse is sent. > But this is > basically working around what we think is a design flaw in the whole > endresponse idea. > > >> Looking at this more closely, there ought to be a try/finally in >> there so that sleep() always gets called if awake() succeeds, >> something like: >> >> > I've thought the same thing, and have been meaning to whine > about it to > the list. If awake runs, sleep should run. And you may be > right; maybe > it should ALWAYS run. That would mean that sleep() has to be coded "defensively" so that it still works properly even if awake() failed halfway through (which is a change to current semantics): def awake(self, trans): Base.awake(self, trans) self._foo = Foo() self._bar = Bar() def sleep(self, trans): if hasattr(self, '_bar'): del self._bar if hasattr(self, '_foo'): del self._foo Base.sleep(self, trans) I used to not like requiring sleep() to be written in this way but I think I'm changing my mind -- this may be the best way to go. I'd like to hear other opinions though. I usually don't even bother writing a sleep() because there's no harm in leaving around the values I've stored in self until the next request. - Geoff |
From: Matt F. <ma...@da...> - 2004-02-19 23:29:00
|
Geoffrey Talvola wrote: >That would mean that sleep() has to be coded "defensively" so that it still >works properly even if awake() failed halfway through (which is a change to >current semantics): > > I remember that this was basically the result of our discussions, yes. At the time, I thought it was better to be defensive and notice the occasional exception than to have unpredictable things happen because cleanup doesn't get run. > def sleep(self, trans): > if hasattr(self, '_bar'): del self._bar > if hasattr(self, '_foo'): del self._foo > Base.sleep(self, trans) > > It's pretty easy just to set them to None. No tests required then. That's what we do. >I used to not like requiring sleep() to be written in this way but I think >I'm changing my mind -- this may be the best way to go. I'd like to hear >other opinions though. > >I usually don't even bother writing a sleep() because there's no harm in >leaving around the values I've stored in self until the next request. > We often do a bunch of state-related cleanup in sleep... Sure, we could just clean up in the next round of awake... make sure that sane defaults are there before we do anything. What about something like a database connection (oh, say, maybe a ZODB connection ;-)? You'd need to close/release it sometime. |
From: Ben P. <be...@we...> - 2004-02-20 00:15:43
|
Let's split this into another thread (was: "RE: [Webware-discuss] Re: [ZODB-Dev] Webkit Threading and ZODB 3. 3a2: problems on Windows") > -----Original Message----- > From: web...@li... > [mailto:web...@li...]On Behalf Of Matt > Feifarek > Sent: Thursday, February 19, 2004 3:29 PM > To: Geoffrey Talvola > Cc: WebWare mailing list > Subject: Re: [Webware-discuss] Re: [ZODB-Dev] Webkit Threading and ZODB > 3. 3a2: problems on Windows > > > Geoffrey Talvola wrote: > > >That would mean that sleep() has to be coded "defensively" so > that it still > >works properly even if awake() failed halfway through (which is > a change to > >current semantics): > > > > > I remember that this was basically the result of our discussions, yes. > At the time, I thought it was better to be defensive and notice the > occasional exception than to have unpredictable things happen because > cleanup doesn't get run. > > > def sleep(self, trans): > > if hasattr(self, '_bar'): del self._bar > > if hasattr(self, '_foo'): del self._foo > > Base.sleep(self, trans) > > > > > It's pretty easy just to set them to None. No tests required then. > That's what we do. > > >I used to not like requiring sleep() to be written in this way > but I think > >I'm changing my mind -- this may be the best way to go. I'd like to hear > >other opinions though. > > > >I usually don't even bother writing a sleep() because there's no harm in > >leaving around the values I've stored in self until the next request. > > > We often do a bunch of state-related cleanup in sleep... > > Sure, we could just clean up in the next round of awake... make sure > that sane defaults are there before we do anything. > > What about something like a database connection (oh, say, maybe a ZODB > connection ;-)? You'd need to close/release it sometime. > I'm against having to write sleep() defensively for a few reasons, but I would like to see sleep() called if awake() completes without exception. So I vote for Geoffrey's first alternate: try: self.awake(transaction) try: self.respond(transaction) finally: self.sleep(transaction) except EndResponse: pass Matt's point about closing state-related operations is big. My suspicion is that most Webware developers use awake()/sleep() to set/unset servlet variables, and don't run into any issue with missing sleep() calls. But if awake and sleep are truly paired functions, and developers code sleep() to clean up work begun in awake(), then sleep should be called in all cases if awake completes without exception. But I don't want to force sleep to run in the case of an exception during awake. My view (I'd love to hear others) is that an unhandled exception in awake() is called a bug and should be fixed in development. I don't want the framework to force me to write sleep() with extra conditional logic to avoid clobbering an exception raised from a bug I may code into awake(). my 2 cents! Ben |
From: Matt F. <ma...@da...> - 2004-02-20 00:28:52
|
Ben Parker wrote: >awake. My view (I'd love to hear others) is that an unhandled exception >in awake() is called a bug and should be fixed in development. I don't want >the framework to force me to write sleep() with extra conditional logic to >avoid clobbering an exception raised from a bug I may code into awake(). > Agreed. And I agree that they should be thought of in pairs; everything that awakes must also sleep. In fact, everything must also respond, but it can do so by sending a redirect or running an action. This has bugged me about WebKit for a while, and we always change our SitePage to make it more consistent: Our servlets ALWAYS do awake - respond - sleep. WriteHTML() is really inside of respond, and is effectively the default "action". Other actions cause WriteHTML to not really run, and you get bone-headed output like: <html><body></body></html> Usually, when an action is run, you either want to redirect somewhere OR do some output. Either way, there is still a response. But the output chain that is so nice in WK is short-circuited with actions. Also, I'm not sure that the action should be called from respond... respond should be about sending data to the client. Action is usually used to do some application logic, like saving data to a database. Sometimes it's an alternate output, I suppose... How do most people listening use actions? I suppose that rather than keep complaining, I should make a proposal. ;-) |
From: Aaron H. <aa...@me...> - 2004-02-20 04:19:26
|
Matt Feifarek wrote: > Ben Parker wrote: > >> awake. My view (I'd love to hear others) is that an unhandled exception >> in awake() is called a bug and should be fixed in development. I >> don't want >> the framework to force me to write sleep() with extra conditional >> logic to >> avoid clobbering an exception raised from a bug I may code into awake(). >> > Agreed. > > And I agree that they should be thought of in pairs; everything that > awakes must also sleep. In fact, everything must also respond, but it > can do so by sending a redirect or running an action. > > This has bugged me about WebKit for a while, and we always change our > SitePage to make it more consistent: > > Our servlets ALWAYS do awake - respond - sleep. WriteHTML() is really > inside of respond, and is effectively the default "action". Other > actions cause WriteHTML to not really run, and you get bone-headed > output like: > <html><body></body></html> > > Usually, when an action is run, you either want to redirect somewhere > OR do some output. Either way, there is still a response. But the > output chain that is so nice in WK is short-circuited with actions. > > Also, I'm not sure that the action should be called from respond... > respond should be about sending data to the client. Action is usually > used to do some application logic, like saving data to a database. > Sometimes it's an alternate output, I suppose... > > How do most people listening use actions? > There is a document called Anatomy of a webware transaction that should be reviewed / revised if necessary but what I do: init -> setup long term resources needed for the servlet (load and compile all templates) awake -> sets up any per page resource (usually session/user based -> select template for this user, open a db conn) respond -> deal w/ specific page request. If there is an action execute it, otherwise run writeHTML sleep -> close down any per page resources (close db conn) So you respond to a HTTP GET/POST. That response will usuall be to execute some code and then write a string. So my action is just a part of the repond phase -Aaron > I suppose that rather than keep complaining, I should make a proposal. > ;-) > > > ------------------------------------------------------- > SF.Net is sponsored by: Speed Start Your Linux Apps Now. > Build and deploy apps & Web services for Linux with > a free DVD software kit from IBM. Click Now! > http://ads.osdn.com/?ad_id=1356&alloc_id=3438&op=click > _______________________________________________ > Webware-discuss mailing list > Web...@li... > https://lists.sourceforge.net/lists/listinfo/webware-discuss |
From: <so...@la...> - 2004-02-20 09:24:49
|
On Thu, Feb 19, 2004 at 07:27:39PM -0500, Matt Feifarek wrote: > How do most people listening use actions? In fact for me no action -> writeHTML(), i don't use writeBody or other stuff at all. But i think that we should take a look at that. why we aren't write something like this class MyPage(Page): ... def actions(self): return ['writehml','addData'...] def writehtml(self): .. or even better twist the writeHML() to render() or something more high level... Another thing, how can i have action w/ long name, like this <input type="submit" name="_actions_" value="Save this"> I can't write the def Save this(self), due to space trouble .. someone can help me ? Bye Bye .. |
From: Matt F. <ma...@da...> - 2004-02-20 17:11:32
|
so...@la... wrote: >Another thing, how can i have action w/ long name, like this ><input type="submit" name="_actions_" value="Save this"> >I can't write the def Save this(self), due to space trouble .. >someone can help me ? > Your action syntax is slightly wrong. (It may be the "old-style" syntax, though). The correct syntax is <input type="submit" name="_actions_save" value="Save this"> and then your method name can be "save". It seems that you're interested in controlling the label on the button. If you want to put spaces into function names in python, I can't help you ;-) |
From: Ian B. <ia...@co...> - 2004-02-20 16:58:54
|
Matt Feifarek wrote: > And I agree that they should be thought of in pairs; everything that > awakes must also sleep. In fact, everything must also respond, but it > can do so by sending a redirect or running an action. > > This has bugged me about WebKit for a while, and we always change our > SitePage to make it more consistent: > > Our servlets ALWAYS do awake - respond - sleep. WriteHTML() is really > inside of respond, and is effectively the default "action". Other > actions cause WriteHTML to not really run, and you get bone-headed > output like: > <html><body></body></html> > > Usually, when an action is run, you either want to redirect somewhere OR > do some output. Either way, there is still a response. But the output > chain that is so nice in WK is short-circuited with actions. I have that problem as well, and tend not to use actions as a result -- I find it easier just to do a test in awake(). Since I usually redirect after an "action" (which is also typically a POST), it doesn't come up too much. Though when it does I just slog through without any framework goodness. In CVS I moved the awake/respond/sleep cycle into the servlet itself, so that you can more easily override the behavior, and particularly so you can do your own exception handling (like a try:finally:) without hacking the WebKit code. So runTransaction() becomes the single entry point for a servlet, and it in turn calls awake/respond/sleep (oh, and I guess it does so with a finally to call sleep -- I thought people had consensed that was the right behavior a while ago). Oh, and then for some messiness, there's the ability to run a specific method of a servlet (blech) and some other hackiness. These drive me nuts, because there semantics and how they fit into the workflow seems unclear to me. I never use any of them -- anything that fancy should go into non-servlet libraries, IMHO. Ian |
From: Ben P. <be...@we...> - 2004-02-20 22:25:42
|
Matt Feifarek wrote: > > Ben Parker wrote: > > >awake. My view (I'd love to hear others) is that an unhandled exception > >in awake() is called a bug and should be fixed in development. I > don't want > >the framework to force me to write sleep() with extra > conditional logic to > >avoid clobbering an exception raised from a bug I may code into awake(). > > > Agreed. > > And I agree that they should be thought of in pairs; everything that > awakes must also sleep. In fact, everything must also respond, but it > can do so by sending a redirect or running an action. > > This has bugged me about WebKit for a while, and we always change our > SitePage to make it more consistent: > > Our servlets ALWAYS do awake - respond - sleep. WriteHTML() is really > inside of respond, and is effectively the default "action". Other > actions cause WriteHTML to not really run, and you get bone-headed > output like: > <html><body></body></html> > > Usually, when an action is run, you either want to redirect somewhere OR > do some output. Either way, there is still a response. But the output > chain that is so nice in WK is short-circuited with actions. > > Also, I'm not sure that the action should be called from respond... > respond should be about sending data to the client. Action is usually > used to do some application logic, like saving data to a database. > Sometimes it's an alternate output, I suppose... > > How do most people listening use actions? > > I suppose that rather than keep complaining, I should make a proposal. ;-) > Inside the respond function is a bit more Pythonic - there's a million and one ways to deal with actions and writing HTML. For some installations, we've modified _respond in a Page subclass to always call writeHTML after an action, unless there was a redirect during awake or an action (this structure is from the pre-"endResponse()" days). So the last few lines of _respond are something like: if not transaction.response().hasHeader('Location'): self.writeHTML() Sometimes I'll have actions that actually write the HTML to the response, sometimes I'll have actions that generate HTML and store it in the servlet until writeHTML() draws it in a particular spot on the page, and sometimes I'll have actions that just perform data modification and write no HTML (ie redirect). But just last month I used an outside contractor to convert some admin screens from JSP into Webware servlets. And his first inclination was to require an _action_ field for every page view, and bypass writeHTML all together. For example, the EditWidget page may have both "Add new widget" and "Edit existing widget" modes, and he put all the HTML into action functions, requiring the page to be requested with either: http://.../EditWidget?_action_=new or http://.../EditWidget?_action_=edit Then was would have been the "save" action is handled inside either of those. Not my normal approach, but I had never thought of doing it that way before so I though I'd mention it. - Ben |
From: Matt F. <ma...@da...> - 2004-02-19 22:10:42
|
Geoffrey Talvola wrote: >Aha. Exceptions can definitely cause sleep() to be skipped. > >If an exception happens during respond() or during awake() then sleep() does >not get called. This smells like a bug to me. > > I always thought that this was funny. We wrap up the EndResponse(s) that we raise with a .cleanup() method (which is usually called from sleep). SO, we're still cleaning up, even when EndResponse is sent. But this is basically working around what we think is a design flaw in the whole endresponse idea. >Looking at this more closely, there ought to be a try/finally in there so >that sleep() always gets called if awake() succeeds, something like: > > I've thought the same thing, and have been meaning to whine about it to the list. If awake runs, sleep should run. And you may be right; maybe it should ALWAYS run. |