myfaces-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Leonardo Uribe <lu4...@gmail.com>
Subject Re: Issues using View Pooling - ViewScope is missing for static structure views?
Date Fri, 27 Mar 2015 19:48:16 GMT
Hi

Ok, good to know that. Thinking about the problem described, I think
it could be related to this one (already fixed in 2.2.7):

https://issues.apache.org/jira/browse/MYFACES-3944
Calls to fcc.startComponentUniqueIdSection(...) and
fcc.endComponentUniqueIdSection(...) should be surrounded in a try
finally block

FaceletState map relies on id generation algorithm to work correctly,
so any problem in the id algorithm will affect that one too.

An example or a log could be a big help to understand what's going on.
Let me explain how it works.
org.apache.myfaces.view.facelets.tag.jsf.FaceletState holds a map with
some EL expressions that are used as an "indirection", so the EL in
the view can be static and in that way cached and finally used in the
view pool. To do that, each EL expression that requires it holds an
unique key generated based on the id algorithm. If there is a
NullPointerException, that means there is something wrong with that
algorithm, because theoretically it should always match. But the
ViewPoolProcesor do some special handling over FaceletState, because
this object helps to decide if the view is dynamic or static.

regards,

Leonardo

2015-03-26 4:09 GMT-05:00 Chris Kulinski <chriskulinski@yahoo.com>:
> Thanks Leonardo!
>
> We confirmed that both your fixes resolved the issues we reported.   We can
> set oamEnableViewPool="false" on specific views and also we're no longer
> seeing issues with ViewScope beans in static structure views.  Thanks for
> the quick resolution to the defects.
>
> We've uncovered an additional defect in our testing that appears to be the
> same NullPointerException issue in FaceletStateValueExpression.getValue() as
> this thread.  http://markmail.org/thread/mvks4ty2v5yvou7m  We'll recreate
> with supplemental logging or create a quick example to show what's
> happening.
>
> Thanks,
> Chris Kulinski
>
>
>
>
> On Wednesday, March 25, 2015 1:11 PM, Leonardo Uribe <lu4242@gmail.com>
> wrote:
>
>
> Hi
>
> I was able to reproduce the problem. Thanks for the log, it helped a
> lot to understand what's going on. It looks like the call to
> restoreState was overriding view scope, so the fix done was add some
> lines to check that case and avoid it. I added some junit tests and on
> the way I fixed a small issue with view root metadata facet.
>
> I hope these fixes will solve your problem. Let us know if that is the
> case or not.
>
> regards,
>
> Leonardo Uribe
>
> 2015-03-24 16:39 GMT-05:00 Chris Kulinski <chriskulinski@yahoo.com>:
>> Leonardo - Thanks for the research and updated cases on the patch. We'll
>> apply your recent changes to our testing and try again.
>>
>> Unfortunately, the additional fixes for this defect didn't fix our other
>> defect with missing View Scope.  I'll create a new issue in the issue
>> tracker to watch this. We'll work on assembling a simple demo that shows
>> the
>> problem.
>>
>> The issue might happen because the View Pooling code doesn't always run
>> during RESTORE_VIEW phase.  It only seems to run in RESTORE_VIEW for AJAX
>> post-backs.  Any changes to our ViewScope objects that happen before
>> RENDER_RESPONSE are lost because it looks like the ViewScope is sometimes
>> reattached at RENDER_RESPONSE.
>>
>> We've added manual debugging to the MyFaces source to attempt to show the
>> problem.  Does this help enough to troubleshoot what's happening?
>>
>> On the very first request to the view after application startup, the
>> behavior is correct. I guess this is because the View hasn't been flushed
>> and remapped by the pool yet.  There is a second instance of the Bean
>> created, but that's maybe after the view is rendered (in
>> saveViewRootState,
>> storeStatic and pushStaticStructureView).
>>
>> 2015-03-24 16:48:23,235 DEBUG
>> [com.autotrader.enterprise.common.context.LogPhaseListener] (default
>> task-1)
>> Start Phase RESTORE_VIEW(1)
>> 2015-03-24 16:48:23,374 DEBUG
>> [com.autotrader.enterprise.common.context.LogPhaseListener] (default
>> task-1)
>> End Phase RESTORE_VIEW(1)
>> 2015-03-24 16:48:23,400 INFO  [stdout] (default task-1)
>> HelloCdiTwoScopedBean - constructed new instance
>> 2015-03-24 16:48:23,406 DEBUG
>> [com.autotrader.enterprise.common.context.LogPhaseListener] (default
>> task-1)
>> Start Phase RENDER_RESPONSE(6)
>> 2015-03-24 16:48:23,420 INFO  [stdout] (default task-1) POOLING:
>> retrieveStaticStructureMetadata root:/examples/ajaxsamples/helloAjax.xhtml
>>
>> key:org.apache.myfaces.view.facelets.pool.impl.MetadataViewKeyImpl@f7711892
>> 2015-03-24 16:48:23,420 INFO  [stdout] (default task-1) POOLING:
>> retrieveStaticStructureMetadata metadatanull
>> 2015-03-24 16:48:23,505 INFO  [stdout] (default task-1) POOLING
>> root:/examples/ajaxsamples/helloAjax.xhtml dynamic:false
>> 2015-03-24 16:48:23,505 INFO  [stdout] (default task-1) POOLING:
>> saveViewRootState root:/examples/ajaxsamples/helloAjax.xhtml
>> 2015-03-24 16:48:23,506 INFO  [stdout] (default task-1) POOLING:
>> storeStatic
>> root:/examples/ajaxsamples/helloAjax.xhtml
>> keyorg.apache.myfaces.view.facelets.pool.impl.MetadataViewKeyImpl@f7711892
>> 2015-03-24 16:48:23,551 INFO  [stdout] (default task-1)
>> HelloCdiTwoViewScopedBean - constructed new instance
>> 2015-03-24 16:48:23,681 INFO  [stdout] (default task-1) POOLING:
>> pushStaticStructureView
>>
>> key:org.apache.myfaces.view.facelets.pool.impl.MetadataViewKeyImpl@f7711892
>> entry:org.apache.myfaces.view.facelets.pool.impl.SoftViewEntry@27ed7f
>> 2015-03-24 16:48:23,683 DEBUG
>> [com.autotrader.enterprise.common.context.LogPhaseListener] (default
>> task-1)
>> End Phase RENDER_RESPONSE(6)
>>
>> On the next request, Pooling isn't executed until during RENDER_RESPONSE.
>> This bean is created after RESTORE_VIEW, but before RENDER_RESPONSE (via
>> PrettyFaces).  The view is using a 2nd instance of the Bean for rendering,
>> without the values from the initial instance (after
>> popStaticStructureView).
>>
>> 2015-03-24 17:18:51,090 DEBUG
>> [com.autotrader.enterprise.common.context.LogPhaseListener] (default
>> task-6)
>> Start Phase RESTORE_VIEW(1)
>> 2015-03-24 17:18:51,091 DEBUG
>> [com.autotrader.enterprise.common.context.LogPhaseListener] (default
>> task-6)
>> End Phase RESTORE_VIEW(1)
>> 2015-03-24 17:18:51,093 INFO  [stdout] (default task-6)
>> HelloCdiTwoScopedBean - constructed new instance
>> 2015-03-24 17:18:51,094 DEBUG
>> [com.autotrader.enterprise.common.context.LogPhaseListener] (default
>> task-6)
>> Start Phase RENDER_RESPONSE(6)
>> 2015-03-24 17:18:51,094 INFO  [stdout] (default task-6) POOLING:
>> retrieveStaticStructureMetadata root:/examples/ajaxsamples/helloAjax.xhtml
>>
>> key:org.apache.myfaces.view.facelets.pool.impl.MetadataViewKeyImpl@f7711892
>> 2015-03-24 17:18:51,094 INFO  [stdout] (default task-6) POOLING:
>> retrieveStaticStructureMetadata
>>
>> metadataorg.apache.myfaces.view.facelets.pool.impl.ViewStructureMetadataImpl@15744d1
>> 2015-03-24 17:18:51,094 INFO  [stdout] (default task-6) POOLING:
>> popStaticStructureView
>>
>> key:org.apache.myfaces.view.facelets.pool.impl.MetadataViewKeyImpl@f7711892
>> q:org.apache.myfaces.view.facelets.pool.impl.ViewPoolEntryHolder@672a58
>> 2015-03-24 17:18:51,098 INFO  [stdout] (default task-6)
>> HelloCdiTwoScopedBean - constructed new instance
>> 2015-03-24 17:18:51,099 INFO  [stdout] (default task-6)
>> HelloCdiTwoViewScopedBean - constructed new instance
>> 2015-03-24 17:18:51,113 DEBUG
>> [com.autotrader.enterprise.common.context.LogPhaseListener] (default
>> task-6)
>> End Phase RENDER_RESPONSE(6)
>>
>> Example of same page, but on an AJAX post-back where Pooling is executed
>> during RESTORE_VIEW. In this case the view scope bean instance is reused
>> and
>> the correct behavior is seen:
>>
>> 2015-03-24 17:39:09,095 DEBUG
>> [com.autotrader.enterprise.common.context.LogPhaseListener] (default
>> task-29) Start Phase RESTORE_VIEW(1)
>> 2015-03-24 17:39:09,096 INFO  [stdout] (default task-29) POOLING
>> restoreView:/examples/ajaxsamples/helloAjax.xhtml
>> state:[Ljava.lang.Object;@f17424
>> 2015-03-24 17:39:09,096 INFO  [stdout] (default task-29) POOLING
>> restoreView:/examples/ajaxsamples/helloAjax.xhtml
>> state:[Ljava.lang.Object;@f17424 view:null
>>
>> metadata:org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage$FaceletViewMetadata@1ffeb0b
>> 2015-03-24 17:39:09,097 INFO  [stdout] (default task-29) POOLING
>> restoreView:/examples/ajaxsamples/helloAjax.xhtml
>> viewRootState:[Ljava.lang.Object;@a04b49
>> 2015-03-24 17:39:09,097 INFO  [stdout] (default task-29) POOLING:
>> retrieveStaticStructureMetadata root:/examples/ajaxsamples/helloAjax.xhtml
>>
>> key:org.apache.myfaces.view.facelets.pool.impl.MetadataViewKeyImpl@f7711892
>> 2015-03-24 17:39:09,097 INFO  [stdout] (default task-29) POOLING:
>> retrieveStaticStructureMetadata
>>
>> metadataorg.apache.myfaces.view.facelets.pool.impl.ViewStructureMetadataImpl@15744d1
>> 2015-03-24 17:39:09,097 INFO  [stdout] (default task-29) POOLING:
>> popStaticStructureView
>>
>> key:org.apache.myfaces.view.facelets.pool.impl.MetadataViewKeyImpl@f7711892
>> q:org.apache.myfaces.view.facelets.pool.impl.ViewPoolEntryHolder@672a58
>> 2015-03-24 17:39:09,097 INFO  [stdout] (default task-29) POOLING
>> restoreView:/examples/ajaxsamples/helloAjax.xhtml
>> vdl.buidlView:javax.faces.component.UIViewRoot@1aeb033
>> 2015-03-24 17:39:09,098 DEBUG
>> [com.autotrader.enterprise.common.context.LogPhaseListener] (default
>> task-29) End Phase RESTORE_VIEW(1)
>>
>>
>> Thanks!
>> Chris Kulinski
>>
>>
>>
>>
>> On Monday, March 23, 2015 10:15 PM, Leonardo Uribe <lu4242@gmail.com>
>> wrote:
>>
>>
>> Hi
>>
>> Thanks for your kind words about the view pooling algorithm :-).
>>
>> It looks there are two issues here.
>>
>> - Add null check on pushPartialView(...) : The solution is correct,
>> I'll commit it soon.
>>
>> - View scope not restored correctly on static structure views : I have
>> not been able to reproduce the problem (it works for me with the
>> latest code, and I do not see a bug in the code). The algorithm used
>> to deal with static/partial and the algorithm for dynamic views has
>> some differences, so it should be something very specific that
>> activates the problem. If you can provide a simple demo that shows the
>> problem, that would be very helpful. The problem with these kind of
>> issues is they are usually really hard to debug, because reproduce
>> them can be very difficult. Anyway, please open a new issue on myfaces
>> issue tracker, so we can keep track on this.
>>
>> regards,
>>
>> Leonardo Uribe
>>
>>
>> 2015-03-22 20:04 GMT-05:00 Chris Kulinski
>> <chriskulinski@yahoo.com.invalid>:
>>> We're testing the View Pooling features of MyFaces 2.2.x on a large
>>> pre-existing JSF site with very complex and heavy views with lots of
>>> composite components.
>>> The performance improvement is frankly amazing - we've gone from GC
>>> events
>>> every few seconds under heavy load to virtually no GC events at all...
>>> Kudos to Leonardo for building in this feature!
>>> We've encountered one specific issue - a NullPointerException when using
>>> oamEnableViewPool="false" to disable pooling for specific views.  We've
>>> created https://issues.apache.org/jira/browse/MYFACES-3966 for this
>>> issue.
>>> We needed to disable pooling for certain views because we noticed issues
>>> with "static structure" views when using ViewScope.  Our ViewScope beans
>>> are
>>> available in our controller code, but are no longer available during the
>>> Render Response phase in our xhtml pages - via expression language
>>> lookups.
>>>    - On the very first request to the view (before its placed in the
>>> pool), the state is applied correctly - but then every subsequent request
>>> to
>>> the pooled view doesn't have the correct view state.
>>>
>>>    - It looks like the view state hasn't been correctly applied on the
>>> view after its retrieved from the pool.
>>> Ways we've been able to work around this issue:
>>>    - If we disable view pooling for these views, then the beans are
>>> correctly available in ViewScope.
>>>
>>>    - We don't see this issue on any of our "dynamic structure" views - in
>>> fact, if we convert the static structure view to a dynamic structure view
>>> (via an extra ui:include with EL, etc), then the view state is mapped
>>> correctly and the viewscope beans are available. There must some pooling
>>> state restore logic that's missing from static structure logic?
>>>
>>> Has anyone else seen this issue?  Or has anyone implemented view pooling
>>> with static and dynamic structure views and view scope?
>>> Thanks!Chris Kulinski
>>>
>>>
>>
>>
>
>

Mime
View raw message