Return-Path: Delivered-To: apmail-xml-cocoon-dev-archive@xml.apache.org Received: (qmail 13286 invoked by uid 500); 30 Oct 2001 07:12:14 -0000 Mailing-List: contact cocoon-dev-help@xml.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: list-post: Reply-To: cocoon-dev@xml.apache.org Delivered-To: mailing list cocoon-dev@xml.apache.org Received: (qmail 13275 invoked from network); 30 Oct 2001 07:12:13 -0000 From: "Carsten Ziegeler" To: Subject: RE: [RT] Resource Garbage Collection Date: Tue, 30 Oct 2001 08:13:27 +0100 Message-ID: MIME-Version: 1.0 X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2911.0) Importance: Normal X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000 In-Reply-To: <00a101c160c0$f6339ed0$7da4558b@vgritsenkopc> X-MIMETrack: Itemize by SMTP Server on PBSN1/Systeme und Netzwerke(Release 5.0.8 |June 18, 2001) at 30.10.2001 08:12:19, Serialize by Router on PBSN1/Systeme und Netzwerke(Release 5.0.8 |June 18, 2001) at 30.10.2001 08:12:20, Serialize complete at 30.10.2001 08:12:20 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="us-ascii" X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N > Vadim Gritsenko wrote: > > Carsten, > > Could the behavior of RequestModelComponent achieved by using object > model: > > if(environment.getObjectModel().get("statistics")==null) > environment.getObjectModel().put("statistics", new X()) > > I used (something like) this when implemented profiler... > Hi Vadim, no not exactly. If your component needs some initialization you have everywhere you need such a component the following lines: if (objectModel contains not object) { create object init object put object in objectModel } And the other problem is that you have to release these objects sometime again. So any mechanism must be provided which looks for all these objects after the request is finished and releases them. Carsten > PS Not that I do not agree with this proposal, I do see necessity for > this interface. > > Vadim > > > -----Original Message----- > > From: Carsten Ziegeler [mailto:cziegeler@s-und-n.de] > > Sent: Monday, October 29, 2001 10:02 AM > > To: cocoon-dev@xml.apache.org > > Subject: RE: [RT] Resource Garbage Collection > > > > Yes, > > > > garbage collection of resources seems to be a must-have. > > Four weeks ago we discussed with Stefano a similar approach > > which would fit in my eyes directly into this concept > > (See http://marc.theaimsgroup.com/?t=100197769000007&w=2&r=1 > > for the full thread). > > > > The concept summarized: A new marker interface named > RequestModelComponent > > (with regards to the SitemapModelComponent, although the name is not > > the point here) which marks an Avalon Component. > > > > public interface RequestModelComponent extends Component { > > void setup(SourceResolver resolver, Map objectModel) throws > > ProcessingException; > > } > > > > The behaviour for this would be: > > - The first time during a request processing a component marked with > > this interface is looked up, a new instance is created (or got from > > the pool) and the setup method is called. This object is stored > > somewhere so that the ComponentManager has access to it for later > > requests. > > - The second, third.. time during the same request this component is > > looked up, it is get from the store and the setup() method is > > not looked up > > - Every time a release is called on this object, nothing really > happens > > - When the request processing is finished, the ComponentManager > > must really release all stored objects. > > > > So actually objects marked in this way are more or less ThreadSafe > > but per request exists a different instance. > > Although this is not a "real world example" and might not be > appropriate > > modelled, lets imagine a component for statistics. In order to work > > correctly > > this component needs access to the objectModel (to get the request > object > > and > > from that the current requestURI) and it "logs" how many components > are used > > during the processing of one request. > > Imagine a simple pipeline with a generator, transformer and > serializer. > > The generator looksup the "Statistics" component called SCA, it is > created > > from scratch (or taken from a pool) and the setup() method is called. > > The generator now sends his information to SCA. Now the transformer > > looks up a "Statistics" component to send his information. If now a > new > > instance SCB would be created, this instance would not know about the > > information > > previously send to SCA, so we need the same instance SCA here. > > As this instance is already setup there is no need to call this method > > again. > > > > If in the same time a different request is processed parallel which > uses > > the same pipeline (or any other, it doesn't really matter), the > generator > > looks up its own "Statistics" component, which of course can not be > SCA as > > it is used in the other pipeline. > > It is a "new" instance which is used exclusivly in this pipeline. > > > > So summarizing it: > > - a ThreadSafe component is shared by all components in all requests. > > - a "normal" component is not shared at all, each component gets its > own > > instance. > > - a RequestModelComponent is shared by all components in the *same* > request. > > > > Now, implementing this results in a similar behaviour as your > proposal. > > All RequestModelComponents are "collected" during a request by the > > ComponentManager > > and release (= garbage collected) at the end of the request. > > > > Carsten > > > > > > Berin Loritsch wrote: > > > > > > Developing with Cocoon is a fun and rewarding experience, > > > especially because it is hard write non-scalable webapps > > > on the platform. Alot of this has to do with the limitations > > > on the developer, and forcing them to Do the Right Thing(TM). > > > Most of the enhancments have come out of a real need. I > > > believe we have one more. > > > > > > The action we have has an interface that is simple, for a > > > reason. We want to be able to encourage ThreadSafe programming. > > > I don't ever want to lose that. However, we have to come > > > to grips with the fact that not everything follows this > > > ideal world. > > > > > > One example was that someone wanted to use an Action to obtain > > > a resource from a database (XML:DB to be exact), but needed > > > a way to release the resources at the end of the pipeline. > > > I think this is a reasonable request, but it does raise some > > > questions. > > > > > > * Which pipeline? One master pipeline that makes use of > > > aggregation or the "cocoon://" protocol is made up of > > > several shorter pipelines spliced together. > > > > > > * How do we handle action sets? > > > > > > * Should things like this be handled by a different mechanism? > > > > > > So, how do we come up with a model that works? The basic > > > problem restated is that we need a way of holding on to > > > resources for the length of the request. After the request is > > > over, the resource is released. Logically, this makes sense, > > > but putting something like this together is difficult in practice. > > > > > > The issue actually stems from our greatest asset: components. > > > The very Component Based Design that Cocoon is built with affects > > > how things work together. The easiest design to implement is > > > one that acts on immediate need. As an analogy, I will use > > > memory management. > > > > > > In assembly and machine language, the programmer is required to > > > manually set up the work areas, and perform all work within those > > > areas. This is equivalent to Pre-Cocoon days where your logic, > > > content, and display information were all mixed together in one > > > resource. It is the way you work with JSP, ASP, and ColdFusion. > > > We all know this is bad, and don't want to go back to those > > > awful working conditions if we can help it. > > > > > > With the advent of higher level languages like C and C++, we > > > were given the blessing and curse of heap managed memory allocation. > > > It was great because now we didn't need to set asside work areas > > > ahead of time. Sure there was a performance penalty for allowing > > > the OS to set up your memmory allocation and management, but it > > > was worth it. If you were careful, you would allocate and > deallocate > > > your memmory as you needed to. The problem came when you had > > > to have some allocated memmory persist between scopes. It is > > > easy to remember to deallocate memmory when you use it all in the > > > same method. But what if you needed to hand that memmory reference > > > to another method--one that you may not have written? If the > > > memmory was deallocated by that method your were SOL (S**t Out of > > > Luck--a military acronym). This is where Cocoon is now. If > > > a Component is asked for (looked up), you have to be careful to > > > release it--otherwise it *may* cause resource leaks. > > > > > > Then cam Java and a slew of other languages that favor garbage > > > collection to explicit deallocation. You have no direct control > > > over when a memmory area is going to be reclaimed, but you do know > > > it won't happen while you are still referencing it. That means > > > you can pass the memmory reference around your program without > > > fear of it being deallocated. This is where Cocoon needs to go. > > > In other words, Cocoon needs a mechanism to 1 have a reference > > > to a resource (Component or Object) last for an entire request. > > > At the end of the request, the resources are cleaned up. > > > > > > So how do we design something like this without screwing our heads? > > > The first is to narrowly define the scope and access of these > > > objects. The second is to mark these objects with an interface > > > so they can be handled properly. This does require some repurposing > > > of the RequestContext I proposed recently. While many people are > > > against using the RequestContext as a "communications" area, it is > > > perfectly suitable for passing object references for the life of > > > one request. > > > > > > In order for the RequestContext to behave properly, and enforce the > > > contracts of mapping resouces to specific names, the put() method > > > must be write-once. That means you can never overwrite a resource. > > > It also means that the developer needs to be smart about the > resource > > > names he uses. We should not impose a strict naming scheme, but > offer > > > one that should be scalable--especially considering the Cocoon > WebApp > > > proposal by Stefano. > > > > > > One proposed naming scheme would be much like URLs: > > > > > > http://infoplanning.com/schematic-access/user > > > > > > Another would be a simpler form of the above version: > > > > > > infoplanning.com:schematic-access/user > > > > > > Still another solution would be equivalent to the > > > java pakage/classname solution: > > > > > > com.infoplanning.schematic-access.user > > > > > > Using replacement variables, the resources would be named with > > > these variables: > > > > > > ${company.domain}:${project.name}/${object.name} > > > > > > This ensures that the probability of you having a unique name > > > within a system is high. The developer may find that adding > > > one more level to the heirarchy might make sense (i.e. a > > > ${module.name}), but it isn't necessary for most projects. > > > > > > Next, we need to specify where the resource collection happens. > > > In order to maintain the simplest and most portable solution, > > > I would propose the RequestContext be managed by the Cocoon object. > > > That way, it is handled the same no matter what the environment > > > is. > > > > > > Lastly, we need to provide a marker interface for resources that > > > must be properly released when the request is over. Objects like > > > Strings, and non-pooled objects can simply have their references > > > nullified. Other objects like the resources mentioned above > > > need a Reclaimable interface with a single method, reclaim(). > > > For instance: > > > > > > public interface Reclaimable { > > > void reclaim(); > > > } > > > > > > The Reclaimable interface tells the resource to clean up after > itself. > > > It is up to the implementor of the Reclaimable interface to decide > on > > > the exact mechanism. The usual method would be to store a reference > > > to it's pool or component manager and call put() or release() on it. > > > This way, Cocoon is not altered too much architecturally, and the > > > ComponentManager/Selectors are not altered from their purpose. > Finally, > > > it also means that encouraging the use of RequestContext for these > types > > > of things encourages a consistent design and method of cleanup. > > > > > > > --------------------------------------------------------------------- > > > To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org > > > For additional commands, email: cocoon-dev-help@xml.apache.org > > > > > > > > > --------------------------------------------------------------------- > > To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org > > For additional commands, email: cocoon-dev-help@xml.apache.org > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org > For additional commands, email: cocoon-dev-help@xml.apache.org > --------------------------------------------------------------------- To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org For additional commands, email: cocoon-dev-help@xml.apache.org