Re: Pipeline components and Object Model issues
Peter Hunsberger pisze: On 8/19/07, Grzegorz Kossakowski <[EMAIL PROTECTED]> wrote: Same goes for all other SAX events. It's actually one extra get and two puts calls on Map. Rather lightweight, yes? I don't really have time to dive into all the details of the discussion, but Map calls themselves are not necessarily "lightweight". If the map itself can grow to any large size then a get or a put isn't necessarily trivial...? Good point. This map contains references to beans' instances in pipelineScope. Given the fact that it will contain one instance per bean configuration this map will be rather small (less than 10 items). Currently it will contain at the most one item. -- Grzegorz Kossakowski http://reflectingonthevicissitudes.wordpress.com/ *** My Internet Service Provider breaks my internet connection *** *** incessantly so I'll not be able to respond to e-mails *** *** regularly and my work will be somehow irregular. *** *** I'm already trying to switch ISP but it will take handful amount of time. ***
Re: Pipeline components and Object Model issues
On 8/19/07, Grzegorz Kossakowski <[EMAIL PROTECTED]> wrote: > Same goes for all other SAX events. It's actually one extra get and two puts > calls on Map. Rather > lightweight, yes? > I don't really have time to dive into all the details of the discussion, but Map calls themselves are not necessarily "lightweight". If the map itself can grow to any large size then a get or a put isn't necessarily trivial...? -- Peter Hunsberger
Re: Pipeline components and Object Model issues
Joerg Heinicke pisze: If so performance loss would at the most two times slower. What does this mean? This sentence makes no sense to me ;) It was late here when writing this sentence. I meant: if T is time needed for particular pipeline to execute without ScopeChanger, just ouf of reading ScopeChanger's code we can see that if it's enabled new execution time is restricted by < 2*T. If you take into account components that actually do something the performance loss could be less noticeable I think. It's about complexity calculations [1]. Joerg, remember that I'm math student so you can be sure that I'm really familiar with complexity calculations. ;-) We used to even proof that certain algorithm belongs certain complexity class or even that problem is solvable only in certain (or higher) complexity class... :-) Your approach is of O(m*n) with m = number of SAX events and n = number of components. The environment change has to be executed m*n times. With my approach it was only O(1*n). Ignore the number of components it's O(m) vs. O(1) - and number of SAX events can be huge. That's why it is not lightweight. But you must remember about the fact that each SAX event is already processed (usually just forwarded) so whole pipeline's complexity is already O(nm). ScopeChanger adds only constant factor to n*m so complexity class does not change, really. Auto-proxying only starts in chapter 7.9 [2] :) Thanks for a link, I'll at it. You can probably just move the code of ScopeChangerProxy straight to a subclass of AbstractAdvisorAutoProxyCreator (which would be coupled to Spring as a BeanPostProcessor is, actually it is a BeanPostProcessor as well but does the proxying for you) or to a MethodInterceptor. What's the best choice? I see. The best lightweight approach is useless if it does not meet the requirements ;) Let me thnk about it ... Joerg, if you find solution dramatically different (and better when it comes to performance) from ScopeChanger I'll be happy to stand you a beer as soon as there is an occasion... ;-) -- Grzegorz Kossakowski http://reflectingonthevicissitudes.wordpress.com/ *** My Internet Service Provider breaks my internet connection *** *** incessantly so I'll not be able to respond to e-mails *** *** regularly and my work will be somehow irregular. *** *** I'm already trying to switch ISP but it will take handful amount of time. ***
Re: Pipeline components and Object Model issues
On 19.08.2007 18:12 Uhr, Grzegorz Kossakowski wrote: But as you say it has to happen for EACH SAX event. I don't think it's lightweight. It happens hundreds times even for simple HTML pages - per component! Correct me if I'm wrong but I thought that every pipeline component handles (even if it's simple forwarding) every single SAX event, right? Yes. If so performance loss would at the most two times slower. What does this mean? This sentence makes no sense to me ;) If you take into account components that actually do something the performance loss could be less noticeable I think. It's about complexity calculations [1]. Your approach is of O(m*n) with m = number of SAX events and n = number of components. The environment change has to be executed m*n times. With my approach it was only O(1*n). Ignore the number of components it's O(m) vs. O(1) - and number of SAX events can be huge. That's why it is not lightweight. Why do you go this low-level approach and instead of just implementing a MethodInterceptor applied with Spring's AOP. That makes it independent from Spring itself since the interceptor can be applied differently later. I'm not Spring specialist, BeanPostProcessor was the first thing I found in docs (chapter 3) that fitted my needs. I'll adjust my code tomorrow. Auto-proxying only starts in chapter 7.9 [2] :) You can probably just move the code of ScopeChangerProxy straight to a subclass of AbstractAdvisorAutoProxyCreator (which would be coupled to Spring as a BeanPostProcessor is, actually it is a BeanPostProcessor as well but does the proxying for you) or to a MethodInterceptor. What original transformer writer could expect is that it's current state of it's Object Model (wrapper) is visible to the Bar component as it is derived from the transformer. As you guessed it, only unwrapped Object Model will be visible to the Bar component. I see. The best lightweight approach is useless if it does not meet the requirements ;) Let me thnk about it ... Joerg [1] http://en.wikipedia.org/wiki/Computational_complexity_theory [2] http://static.springframework.org/spring/docs/2.0.x/reference/aop-api.html#aop-autoproxy
Re: Pipeline components and Object Model issues
Joerg Heinicke pisze: On 19.08.2007 10:03 Uhr, Grzegorz Kossakowski wrote: Same goes for all other SAX events. It's actually one extra get and two puts calls on Map. Rather lightweight, yes? But as you say it has to happen for EACH SAX event. I don't think it's lightweight. It happens hundreds times even for simple HTML pages - per component! Correct me if I'm wrong but I thought that every pipeline component handles (even if it's simple forwarding) every single SAX event, right? If so performance loss would at the most two times slower. If you take into account components that actually do something the performance loss could be less noticeable I think. Why do you go this low-level approach and instead of just implementing a MethodInterceptor applied with Spring's AOP. That makes it independent from Spring itself since the interceptor can be applied differently later. I'm not Spring specialist, BeanPostProcessor was the first thing I found in docs (chapter 3) that fitted my needs. I'll adjust my code tomorrow. I wonder if that's a requirement at all. IMO a properly scoped OM *is* part of the component setup. So I would not even care if the corresponding code has to be touched. Anyway, I can't see where the simple wrapper approach fails. We'll get kind of a hierarchical OM similar to Spring's hierarchical application contexts. Creating the wrapped OM can happen in the same AOP/ BeanPostProcessor way, but it happens only on setup time and once, not for each SAX event by intercepting the setObjectModel() method: on setObjectModel(parentOM) on component xy do xy.setObjectModel(new ObjectModelWrapper(parentOM)) The ObjectModelWrapper holds a map of local vars and delegates to the parent OM if it can not find a value in its local vars. Ok, so component (let it be transformer) has wrapped OM puts local variable on wrapper only. Now imagine that transformer is BeanFactoryAware that uses some other component (let it be a Foo component) to transform some elements. Foo components depends on Bar component, that in turn depends on Object Model. What original transformer writer could expect is that it's current state of it's Object Model (wrapper) is visible to the Bar component as it is derived from the transformer. As you guessed it, only unwrapped Object Model will be visible to the Bar component. I hope that you understand now why scope and it's changing is needed. -- Grzegorz Kossakowski http://reflectingonthevicissitudes.wordpress.com/ *** My Internet Service Provider breaks my internet connection *** *** incessantly so I'll not be able to respond to e-mails *** *** regularly and my work will be somehow irregular. *** *** I'm already trying to switch ISP but it will take handful amount of time. ***
Re: Pipeline components and Object Model issues
On 17.08.2007 2:45 Uhr, Grzegorz Kossakowski wrote: Not entirely true. ObjectModel can be modified during component's execution at random times, really. It happens all the time in template generator where Object Model is passed almost everywhere and it depends on incoming SAX events if OM will be modified. So it's predictable during setup phase but not during execution. What I meant was that this modification of the OM happens in a predictable way (though potentially overly complex to predict). You can interrupt the processing at let's say the 100th SAX event and you know exactly how it looks like. Doing exactly the same on a second request there will be no difference. Thread execution is not predictable at all. I could agree with you that introduction of scope does not make sense in 1:1-relationship but since component can make internal requests and if we want to provide some environment forwarding/sharing (see COCOON-2050[1] and [RT] The big picture of Servlet Service Framework e-mail[2] for examples where it could be needed) we will need to obtain OM and we should get exactly the same OM component making a request have. I can't see how the environment changer approach is different than the simple wrapper in this regard. Somewhere you have to put the logic for environment forwarding/sharing anyway. Actually this whole problem reminds me of session attributes in portlet environment. From my purist point of view I would say: just don't even think about it! ;) That was just an idea. In the wrapper approach the difference is just about making the parent OM access read-only or also writeable. It won't take much time until the first user is asking for this requirement though I bet ;) Joerg
Re: Pipeline components and Object Model issues
On 19.08.2007 16:30 Uhr, Daniel Fagerstrom wrote: We could do something similar for sitemap components and maybe go further and have convention based autoviring so e.g. a set method that takes a ServletRequest automatically get the one from the call injetcted. No auto-wiring in Spring - it's considered to be evil ;) And what you call convention-based auto-wiring is supported by Spring anyway, so there is no need to do anything. Spring supports auto-wiring by type and by name [1]. So if anybody really wants that, he can activate it. (With exception of the request since it is not available as Spring bean. So you have to invent something else anyway.) Joerg [1] http://static.springframework.org/spring/docs/2.0.x/reference/beans.html#beans-factory-autowire
Re: Pipeline components and Object Model issues
Grzegorz Kossakowski skrev: [Snipping lots of technical details] I want to create dynamic proxies around pipeline components. Actual wrapping would be performed by class implementing BeanPostProcessor interface. Taking one perspective one could say that this it's almost the way as discussed one paragraph above. However, going with this path makes whole pipeline scope completely *orthogonal* to the pipeline and its components' code. No existing class will be touched and there is no requirement on pipeline components' configuration files. No need for custom namespace in XML config, etc. I feel proud of this solution as it solves non-trivial problem just in few lines of code and few config files in transparent way. 8-) Seem like a neat solution. Actually there are more that could be done with BeanPostProcessors. As you know sitemap components has a rather involved life cycle, where they first are created by the container and then the setup method is called in the pipeline to insert the object model, the parameters and some other stuff. Now if these objects already are part of the sitemap scope, we could have a special SitemapModelComponent aware BeanPostProcessor that just takes the needed objects from the current scope and use the for setting up the sitemap component. What is needed is that the right scope is set before looking up the sitemap component from the container. This will only work for prototype scoped beans as we must be sure that they actually are created in the scope where they are looked up. All Springified sitemap components are prototypes, (I don't know how it would work for the Avalon bridge handled components). This far we only have a possible simplification of the setup mechanism. But with other BeanPostProcessors we could get the same style of interceptor based dependecy injection as in Struts2, where various request objects are injected in the action bean based on marker interfaces. We could do something similar for sitemap components and maybe go further and have convention based autoviring so e.g. a set method that takes a ServletRequest automatically get the one from the call injetcted. We could use the same mechanism for a new type of actions that are created in prototype scope and get all dependencies injected by Spring in the sitemap scope. /Daniel
Re: Pipeline components and Object Model issues
On 19.08.2007 10:03 Uhr, Grzegorz Kossakowski wrote: Same goes for all other SAX events. It's actually one extra get and two puts calls on Map. Rather lightweight, yes? But as you say it has to happen for EACH SAX event. I don't think it's lightweight. It happens hundreds times even for simple HTML pages - per component! I want to create dynamic proxies around pipeline components. Actual wrapping would be performed by class implementing BeanPostProcessor interface. Why do you go this low-level approach and instead of just implementing a MethodInterceptor applied with Spring's AOP. That makes it independent from Spring itself since the interceptor can be applied differently later. However, going with this path makes whole pipeline scope completely *orthogonal* to the pipeline and its components' code. I wonder if that's a requirement at all. IMO a properly scoped OM *is* part of the component setup. So I would not even care if the corresponding code has to be touched. Anyway, I can't see where the simple wrapper approach fails. We'll get kind of a hierarchical OM similar to Spring's hierarchical application contexts. Creating the wrapped OM can happen in the same AOP/ BeanPostProcessor way, but it happens only on setup time and once, not for each SAX event by intercepting the setObjectModel() method: on setObjectModel(parentOM) on component xy do xy.setObjectModel(new ObjectModelWrapper(parentOM)) The ObjectModelWrapper holds a map of local vars and delegates to the parent OM if it can not find a value in its local vars. Joerg
Re: Pipeline components and Object Model issues
Grzegorz Kossakowski pisze: Hello, Joerg Heinicke asked[1] me to provide summary of the issue that Daniel raised[2] and outline possible solutions so we can discuss them. I think we should do the same for Object Model. I proposed[5] to create new Spring scope (or reuse sitemap scope that must be implemented). Actually, such scope does, behind-the-scene, what I described one paragraph above. It creates new instance (that may inherit properties from old one) of Object Model when entering pipeline components. Then component is safe to modify Object Model according to its needs or even pass it to subsequent, internal requets (like calling service) and can be sure that Object Model contains only data belongs only to the current component. What's very convenient, Spring scope would be completely transparent to the components and even almost transparent to the pipeline's implementation. Pipeline's code would have to only inform when scope is entered and leaved. On the other hand, there is a subtle difference between threads ran simultaneously and pipeline's components ran simultaneously. In latter case, we are in charge of component's management and execution. That means we know exactly when one or another component is executed so we can modify the same Object Model instance the way that changes to Object Model performed in one component will be not visible in another one. Since switching between components occurs on every SAX event we would have to adjust Object Model on-the-fly for every SAX event and every component in a pipeline. This solution has been proposed[6] by Daniel that gave more detailed description. I've done more research and came to conclusion that we will need to combine ideas of custom scope and environment changer. I'm going discuss technical details here. Implementing custom scope has advantages that were outlined earlier. What I missed before was how class implementing org.springframework.beans.factory.config.Scope interface knows which scope is the active one? How it knows if new bean should be created or there is already one in this scope? In order to keep this information accurate we need to switch scope every time component is switched, which means effectively for every SAX event that comes along the pipeline. We already expressed concerns about such solution because it may be too heavy but if we only change _scope_ it's really lightweight and I expect it to have almost zero impact on performance. The code of such scope changer would look like: public class PipelineComponentScopeChanger implements ContentHandler { //This map will contain only one attribute "beans", this map is shared between all //PipelineScopeChanger instances and PipelineScope class private Map scopeAttributesHolder; //This map holds beans in this scope private Map beansInScope; private ContentHandler nextPipelineComponent; public startElement(String namespaceURI, String localName, String qName, Attributes atts) { private Map currentBeansInScope = (Map)scopeAttributesHolder.get("beans"); scopeAttributesHolder.put(beansInScope); nextPipelineComponent.startElement(namespaceURI, localName, qName, atts); scopeAttributesHolder.put(currentBeansInScope); } } Same goes for all other SAX events. It's actually one extra get and two puts calls on Map. Rather lightweight, yes? Then code of PipelineComponentScope would look like: public class PipelineComponentScope implements Scope { private Map scopeAttributesHolder; public Object get(String name, ObjectFactory objectFactory) { Map scopedBeans = (Map)scopeAttributesHolder.get("beans"); Object scopedObject = scopedBeans.get(name); if (scopedObject == null) { scopedObject = objectFactory.getObject(); scopedBeans.put(name, scopedObject); } return scopedObject; } } You may wonder how this scopedAttributesHolder would be injected into these classes. Before discussing this issue I would like to give you another remark. I showed to you that PipelineComponentScopeChanger would implement ContentHandler so you could thought that I'm going to follow Daniel suggestion[1] to put this changer between pipeline components. Next idea that comes to mind is that we should create this changers in pipeline's code because it's a place where we are in control of all components and can insert these changer. Actually, I'm not going this path, or not literally. I want to create dynamic proxies around pipeline components. Actual wrapping would be performed by class implementing BeanPostProcessor interface. Taking one perspective one could say that this it's almost the way as discussed one paragraph above. However, going with this path makes whole pipeline scope completely *orthogonal* to the pipeline and its components' code. No existing class will be touched and there is no requirement on pipeline components' configuration files. No need for custom n
Re: Pipeline components and Object Model issues
Joerg Heinicke pisze: On 14.08.2007 12:26 Uhr, Grzegorz Kossakowski wrote: The problem is that Object Model is a signleton object (more precisely, with "call" scope defined in cocoon-servlet-service-impl) So the problem is not with internal pipelines at all since they are scoped anyway? Or does this apply only for servlet service? Do other internal protocol still exist at all? Yes, it's not problem with internal pipelines (internal requests made by servlet:) because they are scoped. No, it's general problem and if servlet service is not used this problem emerges in internal requests, also (because scope is not used). What internal proctol do you have in mind? A cocoon: I guess, so it still exists and it's main reason for keeping complicated environment handling and complicated code of sitemap's treeprocessor. Since servlet: protocol replaces (or is going to replace) all functionality of cocoon: we need to start thinking about deprecating it in a future. To elaborate on it further, the situation is similar to the situation when thread-unsafe component is used in two threads at the same time. This comparison does not really apply. You don't get corrupted state but some last-wins situation in case of conflicts. If two components in a pipeline have the same parameter the last one added wins. So the result is actually predictable - but unwanted of course. Not entirely true. ObjectModel can be modified during component's execution at random times, really. It happens all the time in template generator where Object Model is passed almost everywhere and it depends on incoming SAX events if OM will be modified. So it's predictable during setup phase but not during execution. This fully establish analogy between thread-unsafe components and OM, IMO. I wonder if that "scope" makes much sense. It's a 1:1-relationship to the component anyway. What we need is only a wrapper that delegates read-only access to parent object model in case the child could not serve the requested value. Maybe we just talk about the same ... Yes, we talk about the same but I want OM to be casual Spring bean but scoped properly. This way we get necessary wrapper but in transparent way so component's can take advantage of Dependency Injection when it comes to OM. I could agree with you that introduction of scope does not make sense in 1:1-relationship but since component can make internal requests and if we want to provide some environment forwarding/sharing (see COCOON-2050[1] and [RT] The big picture of Servlet Service Framework e-mail[2] for examples where it could be needed) we will need to obtain OM and we should get exactly the same OM component making a request have. Actually this whole problem reminds me of session attributes in portlet environment. A portlet's session attributes work exactly like written above - but all are stored within the global HTTP session though by prefixing the session attribute names with a portlet-unique string. And I wonder how fast we will observe another requirement: "I know that I might break something but I WANT make this attribute globally available." This concept is known in portlet session attributes. You can enforce writing an attribute straight to the global session. See the corresponding methods on PortletSession [1] (actually they call it "scope" as well). From my purist point of view I would say: just don't even think about it! ;) However, I know that from time to time we have bend the rules and the solution already exists with current design. OM can be extended by implementing ObjectModelProvider interface so some entries are added to OM during it's creation. Now you can reference to such bean (that should have prototype scope for example) in pipeline component and modify it directly bypassing all OM mechanisms. This way you lost all protection but you are not limited by any scopes and so on. But I'll repeat: don't do this and if you insist on doing it don't be surprised if something does not work. How is the object model injected into such a sitemap component? Still via setup()? As I said earlier, OM is just a Spring bean so it's going to be injected using Spring's mechanisms. -- Grzegorz Kossakowski http://reflectingonthevicissitudes.wordpress.com/ *** My Internet Service Provider breaks my internet connection *** *** incessantly so I'll not be able to respond to e-mails *** *** regularly and my work will be somehow irregular. *** *** I'm already trying to switch ISP but it will take handful amount of time. ***
Re: Pipeline components and Object Model issues
On 14.08.2007 12:26 Uhr, Grzegorz Kossakowski wrote: The problem is that Object Model is a signleton object (more precisely, with "call" scope defined in cocoon-servlet-service-impl) So the problem is not with internal pipelines at all since they are scoped anyway? Or does this apply only for servlet service? Do other internal protocol still exist at all? To elaborate on it further, the situation is similar to the situation when thread-unsafe component is used in two threads at the same time. This comparison does not really apply. You don't get corrupted state but some last-wins situation in case of conflicts. If two components in a pipeline have the same parameter the last one added wins. So the result is actually predictable - but unwanted of course. I proposed[5] to create new Spring scope (or reuse sitemap scope that must be implemented). Actually, such scope does, behind-the-scene, what I described one paragraph above. It creates new instance (that may inherit properties from old one) of Object Model when entering pipeline components. I wonder if that "scope" makes much sense. It's a 1:1-relationship to the component anyway. What we need is only a wrapper that delegates read-only access to parent object model in case the child could not serve the requested value. Maybe we just talk about the same ... Actually this whole problem reminds me of session attributes in portlet environment. A portlet's session attributes work exactly like written above - but all are stored within the global HTTP session though by prefixing the session attribute names with a portlet-unique string. And I wonder how fast we will observe another requirement: "I know that I might break something but I WANT make this attribute globally available." This concept is known in portlet session attributes. You can enforce writing an attribute straight to the global session. See the corresponding methods on PortletSession [1] (actually they call it "scope" as well). How is the object model injected into such a sitemap component? Still via setup()? Joerg [1] http://www.bluesunrise.com/portlet-api/javax/portlet/PortletSession.html
Re: Pipeline components and Object Model issues
Carsten Ziegeler pisze: We should first think of the intended behaviour and then think of the implementation. I would expect that the ObjectModel stays the same during one single request which might end up to be served through a pipeline consisting of several pipeline components. If a sub request is started (internal call through one of our protocols) this gets a new object model which might inherit the values from the parent or not - this is something we have to decide. I expressed my view on ObjectModel sharing between subrequests in "[RT] The big picture of Servlet Service Framework" mail[1]. It was when I discussed statelessness. So, technically speaking, we might end up with more than one ObjectModel per thread when sub requests are involved. The problem now is the possible sax streaming from a sub request to the parent request where the ObjectModel has to be changed on-the-fly. I don't see why we would have to change Object Model on-the-fly if there are two separate intances - one for subrequest and one for request. Could you give an example? While this direct streaming seems to be very cool in terms of performance, it created so many problems over the past years, that I think we should forget about this direct streaming. A sub request writes its content to a temporary buffer (being this a byte array or a recording of sax streams) and when its finished, the content is streamed from this buffer. This allows to change the whole execution context only twice. But it creates a clean separation between the request and makes implementing things much easier. It also allows to cache sub requests completly and directly stream from the cache Although we have to think about subrequests we need to think about components executed in the original request. As I stated in my first mail I think we need several Object Model instances even if there are no subrequests. It is caused by the fact that components are executed simultaneously and my very own opinion is we should not try to change this. I think if we find solution for this we will get solution for subrequests as well. [1] http://article.gmane.org/gmane.text.xml.cocoon.devel/74571 -- Grzegorz Kossakowski http://reflectingonthevicissitudes.wordpress.com/ *** My Internet Service Provider breaks my internet connection *** *** incessantly so I'll not be able to respond to e-mails *** *** regularly and my work will be somehow irregular. *** *** I'm already trying to switch ISP but it will take handful amount of time. ***
Re: Pipeline components and Object Model issues
We should first think of the intended behaviour and then think of the implementation. I would expect that the ObjectModel stays the same during one single request which might end up to be served through a pipeline consisting of several pipeline components. If a sub request is started (internal call through one of our protocols) this gets a new object model which might inherit the values from the parent or not - this is something we have to decide. So, technically speaking, we might end up with more than one ObjectModel per thread when sub requests are involved. The problem now is the possible sax streaming from a sub request to the parent request where the ObjectModel has to be changed on-the-fly. While this direct streaming seems to be very cool in terms of performance, it created so many problems over the past years, that I think we should forget about this direct streaming. A sub request writes its content to a temporary buffer (being this a byte array or a recording of sax streams) and when its finished, the content is streamed from this buffer. This allows to change the whole execution context only twice. But it creates a clean separation between the request and makes implementing things much easier. It also allows to cache sub requests completly and directly stream from the cache Does this make sense? Carsten Grzegorz Kossakowski wrote: > Hello, > > Joerg Heinicke asked[1] me to provide summary of the issue that Daniel > raised[2] and outline > possible solutions so we can discuss them. > > The problem is that Object Model is a signleton object (more precisely, > with "call" scope defined in > cocoon-servlet-service-impl) and is passed to the components (pipeline > components) that are executed > somehow simultaneously. This can lead to the serious problems like one > with parameters I described > here[3] and clarified here[4]. > > To elaborate on it further, the situation is similar to the situation > when thread-unsafe component > is used in two threads at the same time. You know, it may lead to > corrupted state and so on. What's > the classical solution for such problem? Creating two separate instances > of components assigned to > each thread respectively. > > I think we should do the same for Object Model. I proposed[5] to create > new Spring scope (or reuse > sitemap scope that must be implemented). Actually, such scope does, > behind-the-scene, what I > described one paragraph above. It creates new instance (that may inherit > properties from old one) of > Object Model when entering pipeline components. Then component is safe > to modify Object Model > according to its needs or even pass it to subsequent, internal requets > (like calling service) and > can be sure that Object Model contains only data belongs only to the > current component. What's very > convenient, Spring scope would be completely transparent to the > components and even almost > transparent to the pipeline's implementation. Pipeline's code would have > to only inform when scope > is entered and leaved. > > On the other hand, there is a subtle difference between threads ran > simultaneously and pipeline's > components ran simultaneously. In latter case, we are in charge of > component's management and > execution. That means we know exactly when one or another component is > executed so we can modify the > same Object Model instance the way that changes to Object Model > performed in one component will be > not visible in another one. Since switching between components occurs on > every SAX event we would > have to adjust Object Model on-the-fly for every SAX event and every > component in a pipeline. This > solution has been proposed[6] by Daniel that gave more detailed > description. > > Personally speaking, I really dislike Object Model changing on-the-fly > idea. It seems rather heavy > and would be hard to understand in the future. I guess that maintenance > cost of it would be higher > than of our custom scope. > Custom scope proved to be working very well in > cocoon-servlet-service-impl so I think we should use > similar concept. > > WDYT? > > [1] http://article.gmane.org/gmane.text.xml.cocoon.devel/74539 > [2] http://article.gmane.org/gmane.text.xml.cocoon.devel/74435 > [3] http://article.gmane.org/gmane.text.xml.cocoon.devel/74455 > [4] http://article.gmane.org/gmane.text.xml.cocoon.devel/74483 > [5] http://article.gmane.org/gmane.text.xml.cocoon.devel/74479 > [6] http://article.gmane.org/gmane.text.xml.cocoon.devel/74435 > -- Carsten Ziegeler [EMAIL PROTECTED]
Pipeline components and Object Model issues
Hello, Joerg Heinicke asked[1] me to provide summary of the issue that Daniel raised[2] and outline possible solutions so we can discuss them. The problem is that Object Model is a signleton object (more precisely, with "call" scope defined in cocoon-servlet-service-impl) and is passed to the components (pipeline components) that are executed somehow simultaneously. This can lead to the serious problems like one with parameters I described here[3] and clarified here[4]. To elaborate on it further, the situation is similar to the situation when thread-unsafe component is used in two threads at the same time. You know, it may lead to corrupted state and so on. What's the classical solution for such problem? Creating two separate instances of components assigned to each thread respectively. I think we should do the same for Object Model. I proposed[5] to create new Spring scope (or reuse sitemap scope that must be implemented). Actually, such scope does, behind-the-scene, what I described one paragraph above. It creates new instance (that may inherit properties from old one) of Object Model when entering pipeline components. Then component is safe to modify Object Model according to its needs or even pass it to subsequent, internal requets (like calling service) and can be sure that Object Model contains only data belongs only to the current component. What's very convenient, Spring scope would be completely transparent to the components and even almost transparent to the pipeline's implementation. Pipeline's code would have to only inform when scope is entered and leaved. On the other hand, there is a subtle difference between threads ran simultaneously and pipeline's components ran simultaneously. In latter case, we are in charge of component's management and execution. That means we know exactly when one or another component is executed so we can modify the same Object Model instance the way that changes to Object Model performed in one component will be not visible in another one. Since switching between components occurs on every SAX event we would have to adjust Object Model on-the-fly for every SAX event and every component in a pipeline. This solution has been proposed[6] by Daniel that gave more detailed description. Personally speaking, I really dislike Object Model changing on-the-fly idea. It seems rather heavy and would be hard to understand in the future. I guess that maintenance cost of it would be higher than of our custom scope. Custom scope proved to be working very well in cocoon-servlet-service-impl so I think we should use similar concept. WDYT? [1] http://article.gmane.org/gmane.text.xml.cocoon.devel/74539 [2] http://article.gmane.org/gmane.text.xml.cocoon.devel/74435 [3] http://article.gmane.org/gmane.text.xml.cocoon.devel/74455 [4] http://article.gmane.org/gmane.text.xml.cocoon.devel/74483 [5] http://article.gmane.org/gmane.text.xml.cocoon.devel/74479 [6] http://article.gmane.org/gmane.text.xml.cocoon.devel/74435 -- Grzegorz Kossakowski http://reflectingonthevicissitudes.wordpress.com/ *** My Internet Service Provider breaks my internet connection *** *** incessantly so I'll not be able to respond to e-mails *** *** regularly and my work will be somehow irregular. *** *** I'm already trying to switch ISP but it will take handful amount of time. ***