[ https://issues.apache.org/jira/browse/EXTCDI-316?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14140257#comment-14140257 ]
Nuno G. de M edited comment on EXTCDI-316 at 9/19/14 10:21 AM: --------------------------------------------------------------- Hi, and once again, I thank you both for the great input. Concerning Majorra implementation: Leo, Majorra in JSF 2.1 using server side state saving, looks at an incoming request, namely at the automatically injected input field: javax.faces.ViewState request parameter, and checks weather it is "stateless" for transient views, or if it is somelhinkg like "logicalMapKey:actualMapKey". If the thing has an actual value in there, JSF will try to recover that view, accessing a special HTTP session property where all the state is serialized. What happens is that regardless of the logical limit of CODI (64 views), by default the JSF standard will allow you only to have up to 15 records in that logical map. After that the LRU put method just knocks out the least recently entry on that map. This is a potential-critical point for issues. The gap between the size of both buffers. But I see from Gerhard's post that CODI has to abstract itself from whichever way the underlying JSF implementation is deciding to manage the view state. But Leo and Gerhard, if CODI is doing exactly what it is supposed to do, can you please clarify-me in terms of view management, what exactly are the responsabilities of CODI? - Is codi's main responsability destroying CDI beans qualified with the View Scope qualifier? Or does it go beyond that to also deal with JSF state managament? - How do you deal with the possibility that CODI can potentially support an infinite number of views per user session, and specific JSF implementation only supports three? Leaking to view destruction of view 1 as soon CODI opens the view 4 for user session? This is beyond the scope of CODI? Finally, may I then ask why the EditableWindowContextManager.close(WindowContext) seems to take a more active role in the distruction of a Window by clearing out the LRU map you use, while the WindowContext.close() seems to - i guess - only wipeout the View Scoped beans? How to projects typically end up using CODI? Say a user does not use Iframes, and accesses every page in the context of a windowId. Now the user opens a new tab which begets its own new window Id. We have now two separate WindowContexts. If the use now decides to close the new tab, those session objects and window scoped SCI beans will continue alive until the end of the user session? Gerhard, concerning your comment about replacing the views in the client side as opposed of doing ti through typical JSF view navigation. You are correct that this does indeed lead to the creation of many more views that a typical use case. By default, when we are navigation from one .xhtml to a new one, we destroy one window and crate a new one. But this also provides an easy manner of cleaning up after beans used that were present in that old view/xhtml. When you go from one page to antoher, you cleanup after all those old beans that were instantiated to support the .xhtml you swapped out. The new page gets fresh independent state, and user sessions are lighter because of this constant destruction of old views. If you do not kill windows frequently, and keep that one single window forever alive, unless you use more than one tab, your window scoped beans end-up being like session scoped beans (e.g. they will last until the end of the session). Do you belive the following is possible with CODI: (a) Each Ifram has its own windowId (as present) (b) Iframe navigation is done he standard JSF way, keepign the view state and windowID that previously occupied the iframe (e.g. no new CODI window context creation, no new JSF view state entry generation) (c) As part of the navigation onto a new view - convesation scoped beans that were active before the POST get wipedout and new convesation scoped beans are created to fill in the new view? That means - demoting very Bean currently annotated with WindowScoped to ConversationScoped, and having an adequate spot in the postback to the server that leads to an .xhtml navigation to do this bean cleaning? If so, where exactly it the spot to place such a WindowContext.destroyAllConverstationScopedBeans() of old xhtml? Many thanks. was (Author: ngdem): Hi, and once again, I thank you both for the great input. Concerning Majorra implementation: Leo, Majorra in JSF 2.1 using server side state saving, looks at an incoming request, namely at the automatically injected input field: javax.faces.ViewState request parameter, and checks weather it is "stateless" for transient views, or if it is somelhinkg like "logicalMapKey:actualMapKey". If the thing has an actual value in there, JSF will try to recover that view, accessing a special HTTP session property where all the state is serialized. What happens is that regardless of the logical limit of CODI (64 views), by default the JSF standard will allow you only to have up to 15 records in that logical map. After that the LRU put method just knocks out the least recently entry on that map. This is a potential-critical point for issues. The gap between the size of both buffers. But I see from Gerhard's post that CODI has to abstract itself from whichever way the underlying JSF implementation is deciding to manage the view state. But Leo and Gerhard, if CODI is doing exactly what it is supposed to do, can you please clarify-me in terms of view management, what exactly are the responsabilities of CODI? - Is codi's main responsability destroying CDI beans qualified with the View Scope qualifier? Or does it go beyond that to also deal with JSF state managament? - How do you deal with the possibility that CODI can potentially support an infinite number of views per user session, and specific JSF implementation only supports three? Leaking to view destruction of view 1 as soon CODI opens the view 4 for user session? This is beyond the scope of CODI? Finally, may I then ask why the EditableWindowContextManager.close(WindowContext) seems to take a more active role in the distruction of a Window by clearing out the LRU map you use, while the WindowContext.close() seems to - i guess - only wipeout the View Scoped beans? How to projects typically end up using CODI? Say a user does not use Iframes, and accesses every page in the context of a windowId. Now the user opens a new tab which begets its own new window Id. We have now two separate WindowContexts. If the use now decides to close the new tab, those session objects and window scoped SCI beans will continue alive until the end of the user session? Gerhard, concerning your comment about replacing the views in the client side as opposed of doing ti through typical JSF view navigation. You are correct that this does indeed lead to the creation of many more views that a typical use case. By default, when we are navigation from one .xhtml to a new one, we destroy one window and crate a new one. But this also provides an easy manner of cleaning up after beans used that were present in that old view/xhtml. When you go from one page to antoher, you cleanup after all those old beans that were instantiated to support the .xhtml you swapped out. The new page gets fresh independent state, and user sessions are lighter because of this constant destruction of old views. If you do not kill windows frequently, and keep that one single window forever alive, unless you use more than one tab, your window scoped beans end-up being like session scoped beans (e.g. they will last until the end of the session). Many thanks. > Close window context view leakge - JSF 2.1 Multiple Iframes per page > -------------------------------------------------------------------- > > Key: EXTCDI-316 > URL: https://issues.apache.org/jira/browse/EXTCDI-316 > Project: MyFaces CODI > Issue Type: Bug > Components: Core > Affects Versions: 1.0.3 > Environment: Oracle GlassFish Server 3.1.2.5 (build 2), jdk1.6.0_45 > Reporter: Nuno G. de M > Original Estimate: 72h > Remaining Estimate: 72h > > Hi, and thank you for your support. > First, I would just like to stat that I am unsure if the "issue" detected in > our application is a real issue within CODI, or if it is we that are misusing > the framework. Therefore, I would be happy to get your input on the issue I > am about to detail. > ISSUE SUMMARY: > - we have a ui architecture comprised by several Iframes within a main page, > where each iframe has its own CODI window context. After several clicks > replacing the content that of a targetIfram by new content, we were having > CODI view context leakage as well as JSF view state leakage. > ISSUE DETAILS: > For historical as well performance reasons reasons, we have a UI that is > composed into several IFrames within a parent portal iframe. This decomposing > of the view into sub-views means the JSF context to serialize-deserialize per > iframe/.xhtml present in the UI is smaller. As opposed to a single big-ui > view state. > An overview of the core iframes invovled would be: > (1) window.top - Contains the Header and a left-side navigation menu > (2) window.top.contentIfram - Iframe Contains your typical page conent > (.xhtml) > (3) window.top.footer - iframe containing a dynamic footer (its own .xhtml) > (4) wintow.top.applet - Iframe that includes an applet > (5) window.top.special - an auxiliary .xhtml that complements the applet data > (6) window.top.clean - iframe that contains an .xhtml to do CODI window > context and JSF sever state cleanup (created to deal with the issue being > explained here) > The BUG in view navigation is the following: > Each time the user interacts with the UI, e.g by clicing on an menu command > button, or on a applet view element, prompting for a new .xhtml view to be > loaded and replace the old .xhtml loaded on a target iframe we leak both a > JSF and CODI window context. > Our steps are the following: > (1) we change the src of the iframe to point to the new view to be loaded > e.g iframe.src = 'urlTonewPageToBeLoaded.xhtml?requestViewParameters' > In this request we do not inclode the old windowId of the iframe being > replaced. Meaning codi will have to create a new view ID for this new page > load. > (2) We also trigger an ajax request to server to have the old codi window > context being closed. > Intially here did: > (2.1)WindowContext wContext = > windowContextManager.getWindowContext('windowIdToClose); > wContext.close() > It turns out that as we did these two steps we had two leakages. > After about 64 clicks on the applet, if we interatcted with views that the > applet had been loading we would have no issues. If we clicked on some of > the older views that had been loaded after the login and not interacted with > since then (e.g. the footer) we would have a view timeout exception. > This happened because with each new iframe.src='newView', CODI was not > cleaning up its window context map, namely the following line: > this.windowContextMap.remove(editableWindowContext.getId()); > is not executed during a WindowContext.close(). > So despite our class to close the window context, the map would continue to > hold the view just closed. After 64 clicks the view uffer of CODI would be > totally populated, and each new click was destroying the one of the least > recently used views. This could be the main menu, this could be the page > content or this could be the footer. > To address this issue, we had to start injecting the > EditableWindowContextManager, and use its close API. > So the procedure for closing a CODI window context avoiding CODI view leakge > turned into a : > Map<String, EditableWindowContext> existingContextIds = > getExistingContextIds(); > windowContextManager.closeWindowContext(windowIdOfContextToClose); > Finally, there was still one last view leakge to address. > Even when we use the > windowContextManager.closeWindowContext(windowIdOfContextToClose), the JSF > view state associate to this view still exists in the JSF view map. > JSF-core (e.g majorra) seems to have a limit of 15 views within this LRU > logical map. > So once we stopped leaking views in CODI, we still had to tackle the leakage > in JSF. Meaning, when we close a CODI window context, we need to the > javax.views.state string to access the JSF map of logical views and remove > them. > Object sessionObj = externalContext.getSession(false); > synchronized (sessionObj) { > Map logicalMap = (Map) externalContext.getSessionMap().get(LOGICAL_VIEW_MAP); > Map actualMap = (Map) logicalMap.get(idInLogicalMap); > actualMap.clear(); > // remove the leaked view from the LRU map of logical > views > logicalMap.remove(idInLogicalMap); > } > ------ > Naturally, an application should normally not have to dig deep into framework > code. One of the two is for sure true: > - either we are misusing CODI to manage our views > - or CODI has an issue > Thanks in advance for any input on this issue. -- This message was sent by Atlassian JIRA (v6.3.4#6332)