From: <ke...@su...> - 2003-07-15 22:50:49
|
We probably could and should deprecate all the context tools that don't use the context in favor of functions. However, the "context-aware" tools like $Form, $Request, etc are still quite useful. To give a concrete example of a custom tool that uses destroy(), we created a ResultSetIteratorTool that can take a SQL expression and return an Iterator that wraps a ResultSet. The tool has to close the ResultSet and release the connection when the request is done. (I realize this is not the preferred aproach for a Web application, but it works great for our desktop app.) I can see similar applications requiring other resources, like files, sockets, HTTP connections etc. So what's the best design for doing this sort of thing? The listener approach is appealing because then only tools that need this functionality would register themselves, so very few listeners would actually be managed. Plus this is analogous to the model used by HttpSessions and ServletContexts. Is the overhead really that great? I suppose an alternative is to put the onus on the Servlet developer to handle the cleanup if they want to use these kinds of tools. WMServlet makes a call to a stub method called destroyContext() after each request. A developer could use a method like this to go into the context and find resources that need to be released. This is more work for the developer, but since this isn't used much, it might make sense to do it this way. Keats -------Original Message------- From: Brian Goetz <br...@qu...> Sent: 07/15/03 05:47 PM To: ma...@an... Subject: Re: [Webmacro-devel] More pruning > > >Well FWIW I think nuking CTs is probably a good idea too, if we can still >get the same $Form functionality etc. > >I've never used a CT, and when I eventually understood the difference >between a CT and an app-supplied helper, I couldn't really see how useful >they are except for saving a few lines of code. They're like functionality built into the context that you don't have to explicitly put there. That's pretty useful, and it allows sites to extend WM on their own by building their own tools for their own specific stuff and having it appear "built in." I personally don't use them often, but I can see how they are very useful. I don't see that nuking them will gain us much. At this point, their impact on the code and on performnace is minimal, and people DO use them. We can encourage people to use global functions instead, now that we have them. -- Brian Goetz Quiotix Corporation br...@qu... Tel: 650-843-1300 Fax: 650-324-8032 http://www.quiotix.com ------------------------------------------------------- This SF.net email is sponsored by: VM Ware With VMware you can run multiple operating systems on a single machine. WITHOUT REBOOTING! Mix Linux / Windows / Novell virtual machines at the same time. Free trial click here: http://www.vmware.com/wl/offer/345/0 _______________________________________________ Webmacro-devel mailing list Web...@li... https://lists.sourceforge.net/lists/listinfo/webmacro-devel > |
From: Brian G. <br...@qu...> - 2003-07-15 22:59:51
|
>So what's the best design for doing this sort of thing? The listener >approach is appealing because then only tools that need this functionality >would register themselves, so very few listeners would actually be >managed. Plus this is analogous to the model used by HttpSessions and >ServletContexts. > >Is the overhead really that great? The performance overhead is negligible. However, the issue you raise below, requiring the WM user to explicitly free the Context is not really negligible, as the lifecycle methods at all levels bubble up to the the level of the user's consciousness. So what if we add these: class Context { ... public void registerDestructor(Destructor dtor) { destructors.add(dtor); } public void destroy() { /* iterate through destructors */ } } which don't affect anyone who's not going to use them. To be polite, we can teach WMServlet about it. And tools that hold things like connections should still probably use finalizers, just in case none of the explicit mechanisms do their job. That seems OK to me. >I suppose an alternative is to put the onus on the Servlet developer to >handle the cleanup if they want to use these kinds of tools. WMServlet >makes a call to a stub method called destroyContext() after each >request. A developer could use a method like this to go into the context >and find resources that need to be released. This is more work for the >developer, but since this isn't used much, it might make sense to do it >this way. -- Brian Goetz Quiotix Corporation br...@qu... Tel: 650-843-1300 Fax: 650-324-8032 http://www.quiotix.com |
From: Marc P. <ma...@an...> - 2003-07-15 23:08:04
|
On Tue, 15 Jul 2003 15:59:12 -0700, Brian Goetz <br...@qu...> wrote: > The performance overhead is negligible. > > However, the issue you raise below, requiring the WM user to explicitly > free the Context is not really negligible, as the lifecycle methods at > all levels bubble up to the the level of the user's consciousness. > > So what if we add these: > > class Context { > ... > public void registerDestructor(Destructor dtor) { destructors.add(dtor); > } > public void destroy() { /* iterate through destructors */ } > } > > which don't affect anyone who's not going to use them. To be polite, we > can teach WMServlet about it. And tools that hold things like > connections should still probably use finalizers, just in case none of > the explicit mechanisms do their job. That seems OK to me. Yes, this sounds good to me too, a listener mechanism :) How about ContextDestroyListener instead of Destructor though? It's less generic but it makes the functionality clearer. Cheers -- Marc Palmer Contract Java Consultant/Developer w a n g j a m m e r s java and web software design experts with an ethical outlook http://www.wangjammers.org |
From: <web...@st...> - 2003-07-16 07:57:36
|
On Tue, 15 Jul 2003, Brian Goetz wrote: | | >So what's the best design for doing this sort of thing? The listener | >approach is appealing because then only tools that need this functionality | >would register themselves, so very few listeners would actually be | >managed. Plus this is analogous to the model used by HttpSessions and | >ServletContexts. | > | >Is the overhead really that great? | | The performance overhead is negligible. | | However, the issue you raise below, requiring the WM user to explicitly | free the Context is not really negligible, as the lifecycle methods at all | levels bubble up to the the level of the user's consciousness. | | So what if we add these: | | class Context { | ... | public void registerDestructor(Destructor dtor) { destructors.add(dtor); } | public void destroy() { /* iterate through destructors */ } | } | | which don't affect anyone who's not going to use them. To be polite, we | can teach WMServlet about it. And tools that hold things like connections | should still probably use finalizers, just in case none of the explicit | mechanisms do their job. That seems OK to me. | | >I suppose an alternative is to put the onus on the Servlet developer to | >handle the cleanup if they want to use these kinds of tools. WMServlet | >makes a call to a stub method called destroyContext() after each | >request. A developer could use a method like this to go into the context | >and find resources that need to be released. This is more work for the | >developer, but since this isn't used much, it might make sense to do it | >this way. Ehh.. I don't get this. A developer -may- adhere to the contract, but he is equally free to just -not- do the cleanup? I feel that -either- one require the developer to do the cleanup (which I don't like - I already -hate- DB Connection-getting and -closing), or there aren't any such "suggestions" at all. I develop a framework. If this "suggested destroy - contract" is in there, I will have to always destroy the Contexts, as I don't know what others will put into the configuration - even though I (as the framework developer) don't use this at all. Endre. |
From: Brian G. <br...@qu...> - 2003-07-16 16:38:21
|
> Ehh.. I don't get this. A developer -may- adhere to the contract, but he > is equally free to just -not- do the cleanup? Some tools require cleanup. Most don't. If you use a tool that requires cleanup and you want those to be cleaned up other than through finalization, tell the context when you're done with it. Most users don't use such tools, so they're fine. |
From: Marc P. <ma...@an...> - 2003-07-16 16:48:37
|
On Wed, 16 Jul 2003 09:37:55 -0700, Brian Goetz <br...@qu...> wrote: >> Ehh.. I don't get this. A developer -may-adhere to the contract, but he >> is equally free to just -not-do the cleanup? > > Some tools require cleanup. Most don't. If you use a tool that > requires cleanup and you want those to be cleaned up other than > through finalization, tell the context when you're done with it. > Most users don't use such tools, so they're fine. I agree with the sentiment about having a contract that does not have to be completely honoured... it doesn't sit well. How about a totally trivial solution. Add a new method to ContextTool: boolean isDestroyRequired(); CTs implement this and return true if they want their destroy() called. This way we have a complete contract for it - implement destroy() accordingly if you return true from isDestroyRequired, and if you never need it just return false and don't do anything in destroy(). How this is handled internally by WM is then opaque to the CT writer, and we can optimise it any way we like (have a pre-populated Set of all CTs that do require destroy() and just iter that). Having said that, I still think the separate interface approach is nicer - so there is no destroy() method in the CT interface. It's tidier. Marc -- Marc Palmer Contract Java Consultant/Developer w a n g j a m m e r s java and web software design experts with an ethical outlook http://www.wangjammers.org |
From: Brian G. <br...@qu...> - 2003-07-16 16:52:18
|
> How about a totally trivial solution. Add a new method to ContextTool: > > > boolean isDestroyRequired(); > > CTs implement this and return true if they want their destroy() called. > This way we have a complete contract for it - implement destroy() > accordingly if you return true from isDestroyRequired, and if you never > need it just return false and don't do anything in destroy(). You are missing the hard part -- how does the Context know when its done? The question is whether we have to make the user explicitly destroy the context, which I don't want to force all users to do just because some tools I've never seen want this. > How this is handled internally by WM is then opaque to the CT writer, and > we can optimise it any way we like (have a pre-populated Set of all CTs > that do require destroy() and just iter that). iter it WHEN? |
From: Marc P. <ma...@an...> - 2003-07-16 16:59:03
|
On Wed, 16 Jul 2003 09:51:57 -0700, Brian Goetz <br...@qu...> wrote: >> How about a totally trivial solution. Add a new method to ContextTool: >> >> >> boolean isDestroyRequired(); >> >> CTs implement this and return true if they want their destroy() called. >> This way we have a complete contract for it - implement destroy() >> accordingly if you return true from isDestroyRequired, and if you never >> need it just return false and don't do anything in destroy(). > > You are missing the hard part -- how does the Context know when its > done? The question is whether we have to make the user explicitly > destroy the context, which I don't want to force all users to do just > because some tools I've never seen want this. Hmmm, well why not have explicity Context "close()" paradigm? It's standard resource allocation stuff. Worst case scenario, we end up with the GC collecting the Context and close() getting called implicitly from the finalizer. That's a worst case the same as what we have now (no recycle() method any more), and a best case where the programmer reads the docs and calls context.close() in a finally block just like they close streams. I don't see a problem here. Either way it will go away eventually, and for those of us with brain cells, it will go away quickly. -- Marc Palmer Contract Java Consultant/Developer w a n g j a m m e r s java and web software design experts with an ethical outlook http://www.wangjammers.org |
From: Brian G. <br...@qu...> - 2003-07-16 17:05:47
|
> Hmmm, well why not have explicity Context "close()" paradigm? It's standard > resource allocation stuff. Worst case scenario, we end up with the GC > collecting the Context and close() getting called implicitly from the > finalizer. Either of these suggestions seems like the worst of both worlds. 1. Why force users to call context.close? Why can't they just let it get garbage collected like everything else, when 99.99% of the time, no one is using anything in the context that requires cleanup? Why make most Context users pay (in convenience) for the sins of the few using tools which require cleanup? 2. If anything has to be finalized, it's NOT going to be the context. Finalization is expensive and really plays havoc with garbage collection. It takes several full GCs for an object with a finalizer to be collected. Why make every WM user pay the GC costs of that? If you're going to use finialization, do it in the tools requiring cleanup, not in the Context. |
From: Marc P. <ma...@an...> - 2003-07-16 17:26:12
|
On Wed, 16 Jul 2003 10:05:27 -0700, Brian Goetz <br...@qu...> wrote: >> Hmmm, well why not have explicity Context "close()" paradigm? It's >> standard resource allocation stuff. Worst case scenario, we end up with >> the GC collecting the Context and close() getting called implicitly from >> the finalizer. > > Either of these suggestions seems like the worst of both worlds. > > 1. Why force users to call context.close? Why can't they just let it > get garbage collected like everything else, when 99.99% of the time, > no one is using anything in the context that requires cleanup? Why > make most Context users pay (in convenience) for the sins of the few > using tools which require cleanup? Aren't you defeating your own argument here? If people like you don't care, they won't pay by calling close() and GC will take care of it just as you want it. If you happen to use CTs that require cleanup then you should call close(), but as you have stated this is a tiny minority of CTs, and as such is unlikely to be called. Once again... it doesn't matter if you don't call it, in the sense that you were proposing a GC-only solution (as is now in CVS) anyway. Adding close() gives people the option to hasten the release of resources if this is an issue for them. As a framework write, I can trivially make sure close() is called and it is never a concern for my developers. > 2. If anything has to be finalized, it's NOT going to be the context. > Finalization is expensive and really plays havoc with garbage > collection. It takes several full GCs for an object with a finalizer > to be collected. Why make every WM user pay the GC costs of that? If > you're going to use finialization, do it in the tools requiring > cleanup, not in the Context. Agreed. Marc -- Marc Palmer Contract Java Consultant/Developer w a n g j a m m e r s java and web software design experts with an ethical outlook http://www.wangjammers.org |
From: Brian G. <br...@qu...> - 2003-07-16 17:46:49
|
> Aren't you defeating your own argument here? If people like you don't care, > they won't pay by calling close() and GC will take care of it just as you > want it. No, but with all the myriad proposals floating around, I'm not surprised that this is all confusing. My positions: - NO finalizer on Context. - No _required_ close/free/destroy/cleanup method on Context -- 99% of what Context does can be handled by GC. - I am not opposed to a subscription-based mechanism for context tools, where they can register a listener, and have an optional method for "signal all the listeners now." But we don't entirely need this -- I'm find with letting tools clean themselves via finalizers or the like. You're right, for frameworks, it doesn't matter at all. But I'm thinking about the trivial WM case, and minimizing the complexity of the basic pattern. I don't like the idea of having a method called "close" but telling people "well, you don't have to use that if don't want to." > If you happen to use CTs that require cleanup then you should call > close(), but as you have stated this is a tiny minority of CTs, and > as such is unlikely to be called. Maybe naming, but not 'close'. How about 'callDestructorsForContextToolsThatCantWipeThemselves', or something like that :) |
From: <web...@st...> - 2003-07-17 07:39:52
|
On Wed, 16 Jul 2003, Marc Palmer wrote: | On Wed, 16 Jul 2003 09:51:57 -0700, Brian Goetz <br...@qu...> wrote: | | >> How about a totally trivial solution. Add a new method to ContextTool: | >> | >> | >> boolean isDestroyRequired(); | >> | >> CTs implement this and return true if they want their destroy() called. | >> This way we have a complete contract for it - implement destroy() | >> accordingly if you return true from isDestroyRequired, and if you never | >> need it just return false and don't do anything in destroy(). | > | > You are missing the hard part -- how does the Context know when its | > done? The question is whether we have to make the user explicitly | > destroy the context, which I don't want to force all users to do just | > because some tools I've never seen want this. | | Hmmm, well why not have explicity Context "close()" paradigm? It's standard | resource allocation stuff. Worst case scenario, we end up with the GC | collecting the Context and close() getting called implicitly from the | finalizer. | | That's a worst case the same as what we have now (no recycle() method any | more), and a best case where the programmer reads the docs and calls | context.close() in a finally block just like they close streams. | | I don't see a problem here. Either way it will go away eventually, and for | those of us with brain cells, it will go away quickly. It is annoying. try-finallies are very, very annoying. And I do agree totally with Brian that as long as there aren't any good reasons for having it (a proper use case or ten), then it is "unfair" forcing me to do resource-deallocation that will most often be totally useless. Endre. |