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... PS Not that I do not agree with this proposal, I do see necessity for this interface. Vadim > -----Original Message----- > From: Carsten Ziegeler [mailto:[EMAIL PROTECTED]] > Sent: Monday, October 29, 2001 10:02 AM > To: [EMAIL PROTECTED] > 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: [EMAIL PROTECTED] > > For additional commands, email: [EMAIL PROTECTED] > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, email: [EMAIL PROTECTED] --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, email: [EMAIL PROTECTED]