You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@wicket.apache.org by Bertrand Guay-Paquet <be...@step.polymtl.ca> on 2012/08/10 15:31:52 UTC
Calling isPageStateless() can mess up the statelessness of a page
Hi,
(Using Wicket 6.0-SNAPSHOT, or 1.5.7)
I found a strange behavior when calling Page#isPageStateless(). I have a
simple label in my personal wicket debug bar which displays "stateless"
when a page is stateless. It works like so:
new WebMarkupContainer("statelessMarker") {
@Override
protected void onConfigure() {
super.onConfigure();
setVisible(getPage().isPageStateless());
}
};
This worked great until I got by chance a page which was stateless
except for ajax links which were children of a repeater. Here is what
happens then:
1) onConfigure() is called which calls isPageStateless() and determines
the page is stateless
2) onBeforeRender() is executed which populates the repeaters and adds
stateful components to the tree
3) Since the page was determined stateless in 1), it stays that way
4) stateful ajax callback links do not work on the page
Therefore, it seems that isPageStateless() should never be called before
onBeforeRender() is executed or mayhem may ensue. However, after cursory
inspection of callers of isPageStateless(), it looks like that is not
always the case so I'm not certain.
Should this be considered a bug? Should an assertion be made in
isPageStateless() that onBeforeRender() was executed?
Regards,
Bertrand
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org
Re: Calling isPageStateless() can mess up the statelessness of a page
Posted by vineet semwal <vi...@gmail.com>.
it actually is "isPageStatelessAtTimeIAmChecking"
i have one idea ..if isPageStateless() is only made to cache that
variable after page#onbeforerender then it will be ok.
if some call is made before that then don't allow caching of that
variable ,it's very easy to make this improvement...
what should be returned if call is made before page#onbeforerender
depends how much you want to deviate from current behvior,you can
return the isPagestateless() without caching with a warning *too early
to check if page is stateless*
or change the return type to Boolean and return null or throw runtimexception.
On Sat, Aug 11, 2012 at 10:33 AM, Bertrand Guay-Paquet
<be...@step.polymtl.ca> wrote:
> This is weird, I never received Martin's email! I managed to see it in your
> first reply Vineet... I also lost a few hours' worth of mailing list emails.
>
> Removing the caching in isPageStateless() would indeed make sure that the
> code in WebPageRenderer would not get the wrong value. However, all the
> calls made to isPageStateless() before that point could still get the wrong
> value returned, depending on the page. In that case, it seems kind of
> pointless to rely on isPageStateless() for anything at all before rendering
> (or at least onBeforeRender) occurs.
>
> I had a deeper look at callers of isPageStateless() in Wicket's source and
> found two possible causes of concern: WebPageRenderer#respond(RequestCycle)
> and ListenerInterfaceRequestHandler#respond(RequestCycle). I'll need to
> examine in them in more details.
>
> To be continued...
>
>
> On 10/08/2012 6:33 PM, vineet semwal wrote:
>>
>> you are right onconfigure is executed once before rendering .
>>
>> actually isPageStateless() can be broken easily as that variable can
>> be populated before the page#onbeforerender is completed ie. say if
>> some component in onbeforerender uses ispagestateless() then the
>> variable will be set prematurely
>>
>> now i see martin-g is correct the solution is to just remove the
>> caching but the problem can be that method is used in a lot of places
>> and can be called many times foreg. it's used inside urlFor in
>> Component which means link will at least call this method once in
>> getUrl and if you have a repeater of 20 links this is 20 X
>> isPageStateless() ,it actually depends on how expensive
>> ispagestateless() itself is and at how many places is it used ..
>>
>>
>> On Fri, Aug 10, 2012 at 10:53 PM, Bertrand Guay-Paquet
>> <be...@step.polymtl.ca> wrote:
>>>
>>> On 10/08/2012 12:12 PM, vineet semwal wrote:
>>>>
>>>> it might give you wrong result even if you add your component after
>>>> adding all the components because some components foreg. a repeater
>>>> like listview/dataview/gridview add children in onbeforerender so
>>>> isPageStateless() can be assumed to work correctly only after
>>>> onbeforerender
>>>
>>> Yes that's exactly what I wanted to say! The repeaters are only populated
>>> in
>>> their onBeforeRender() which is executed after onConfigure().
>>>
>>>
>>>> that caching part is ok imho for isPageStateless() ,actually that
>>>> cached variable is reset in page#onbeforerender which is the another
>>>> reason isPageStateless() should work correctly after onbeforerender
>>>
>>> I hadn't noticed that reset in Page#onBeforeRender() so I had a look
>>> since
>>> it would contradict my observations.
>>>
>>> This is the stack trace when my label's onConfigure() is reached :
>>> TmpPage$1.onConfigure() line: 24 <-- my stateless indicator label;
>>> calls
>>> isPageStateless()
>>> TmpPage$1(Component).configure() line: 1028
>>> TmpPage$1(Component).internalBeforeRender() line: 913
>>> TmpPage$1(Component).beforeRender() line: 990
>>> TmpPage(MarkupContainer).onBeforeRenderChildren() line: 1688
>>> TmpPage(Component).onBeforeRender() line: 3830
>>> TmpPage(Page).onBeforeRender() line: 802 <--- line 799 already did the
>>> reset of the cached "stateless" var
>>> TmpPage(Component).internalBeforeRender() line: 922
>>> TmpPage(Component).beforeRender() line: 990
>>> TmpPage(Component).internalPrepareForRender(boolean) line: 2204
>>> TmpPage(Page).internalPrepareForRender(boolean) line: 247
>>> TmpPage(Component).render() line: 2289
>>> TmpPage(Page).renderPage() line: 1021
>>>
>>> This stack trace occurs before the repeating view is populated which
>>> would
>>> render the page stateful and causes the Page to cache that it is
>>> stateless.
>>>
>>> By the way, I did find a workaround to achieve the desired effect so
>>> that's
>>> not why I brought this up here. I'm just concerned that such erroneous
>>> computations of the page's stateless state might cause other bugs down
>>> the
>>> road.
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>>> For additional commands, e-mail: users-help@wicket.apache.org
>>>
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
--
regards,
Vineet Semwal
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org
Re: Calling isPageStateless() can mess up the statelessness of a
page
Posted by Bertrand Guay-Paquet <be...@step.polymtl.ca>.
This is weird, I never received Martin's email! I managed to see it in
your first reply Vineet... I also lost a few hours' worth of mailing
list emails.
Removing the caching in isPageStateless() would indeed make sure that
the code in WebPageRenderer would not get the wrong value. However, all
the calls made to isPageStateless() before that point could still get
the wrong value returned, depending on the page. In that case, it seems
kind of pointless to rely on isPageStateless() for anything at all
before rendering (or at least onBeforeRender) occurs.
I had a deeper look at callers of isPageStateless() in Wicket's source
and found two possible causes of concern:
WebPageRenderer#respond(RequestCycle) and
ListenerInterfaceRequestHandler#respond(RequestCycle). I'll need to
examine in them in more details.
To be continued...
On 10/08/2012 6:33 PM, vineet semwal wrote:
> you are right onconfigure is executed once before rendering .
>
> actually isPageStateless() can be broken easily as that variable can
> be populated before the page#onbeforerender is completed ie. say if
> some component in onbeforerender uses ispagestateless() then the
> variable will be set prematurely
>
> now i see martin-g is correct the solution is to just remove the
> caching but the problem can be that method is used in a lot of places
> and can be called many times foreg. it's used inside urlFor in
> Component which means link will at least call this method once in
> getUrl and if you have a repeater of 20 links this is 20 X
> isPageStateless() ,it actually depends on how expensive
> ispagestateless() itself is and at how many places is it used ..
>
>
> On Fri, Aug 10, 2012 at 10:53 PM, Bertrand Guay-Paquet
> <be...@step.polymtl.ca> wrote:
>> On 10/08/2012 12:12 PM, vineet semwal wrote:
>>> it might give you wrong result even if you add your component after
>>> adding all the components because some components foreg. a repeater
>>> like listview/dataview/gridview add children in onbeforerender so
>>> isPageStateless() can be assumed to work correctly only after
>>> onbeforerender
>> Yes that's exactly what I wanted to say! The repeaters are only populated in
>> their onBeforeRender() which is executed after onConfigure().
>>
>>
>>> that caching part is ok imho for isPageStateless() ,actually that
>>> cached variable is reset in page#onbeforerender which is the another
>>> reason isPageStateless() should work correctly after onbeforerender
>> I hadn't noticed that reset in Page#onBeforeRender() so I had a look since
>> it would contradict my observations.
>>
>> This is the stack trace when my label's onConfigure() is reached :
>> TmpPage$1.onConfigure() line: 24 <-- my stateless indicator label; calls
>> isPageStateless()
>> TmpPage$1(Component).configure() line: 1028
>> TmpPage$1(Component).internalBeforeRender() line: 913
>> TmpPage$1(Component).beforeRender() line: 990
>> TmpPage(MarkupContainer).onBeforeRenderChildren() line: 1688
>> TmpPage(Component).onBeforeRender() line: 3830
>> TmpPage(Page).onBeforeRender() line: 802 <--- line 799 already did the
>> reset of the cached "stateless" var
>> TmpPage(Component).internalBeforeRender() line: 922
>> TmpPage(Component).beforeRender() line: 990
>> TmpPage(Component).internalPrepareForRender(boolean) line: 2204
>> TmpPage(Page).internalPrepareForRender(boolean) line: 247
>> TmpPage(Component).render() line: 2289
>> TmpPage(Page).renderPage() line: 1021
>>
>> This stack trace occurs before the repeating view is populated which would
>> render the page stateful and causes the Page to cache that it is stateless.
>>
>> By the way, I did find a workaround to achieve the desired effect so that's
>> not why I brought this up here. I'm just concerned that such erroneous
>> computations of the page's stateless state might cause other bugs down the
>> road.
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>> For additional commands, e-mail: users-help@wicket.apache.org
>>
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org
Re: Calling isPageStateless() can mess up the statelessness of a page
Posted by vineet semwal <vi...@gmail.com>.
you are right onconfigure is executed once before rendering .
actually isPageStateless() can be broken easily as that variable can
be populated before the page#onbeforerender is completed ie. say if
some component in onbeforerender uses ispagestateless() then the
variable will be set prematurely
now i see martin-g is correct the solution is to just remove the
caching but the problem can be that method is used in a lot of places
and can be called many times foreg. it's used inside urlFor in
Component which means link will at least call this method once in
getUrl and if you have a repeater of 20 links this is 20 X
isPageStateless() ,it actually depends on how expensive
ispagestateless() itself is and at how many places is it used ..
On Fri, Aug 10, 2012 at 10:53 PM, Bertrand Guay-Paquet
<be...@step.polymtl.ca> wrote:
>
> On 10/08/2012 12:12 PM, vineet semwal wrote:
>>
>> it might give you wrong result even if you add your component after
>> adding all the components because some components foreg. a repeater
>> like listview/dataview/gridview add children in onbeforerender so
>> isPageStateless() can be assumed to work correctly only after
>> onbeforerender
>
> Yes that's exactly what I wanted to say! The repeaters are only populated in
> their onBeforeRender() which is executed after onConfigure().
>
>
>> that caching part is ok imho for isPageStateless() ,actually that
>> cached variable is reset in page#onbeforerender which is the another
>> reason isPageStateless() should work correctly after onbeforerender
>
> I hadn't noticed that reset in Page#onBeforeRender() so I had a look since
> it would contradict my observations.
>
> This is the stack trace when my label's onConfigure() is reached :
> TmpPage$1.onConfigure() line: 24 <-- my stateless indicator label; calls
> isPageStateless()
> TmpPage$1(Component).configure() line: 1028
> TmpPage$1(Component).internalBeforeRender() line: 913
> TmpPage$1(Component).beforeRender() line: 990
> TmpPage(MarkupContainer).onBeforeRenderChildren() line: 1688
> TmpPage(Component).onBeforeRender() line: 3830
> TmpPage(Page).onBeforeRender() line: 802 <--- line 799 already did the
> reset of the cached "stateless" var
> TmpPage(Component).internalBeforeRender() line: 922
> TmpPage(Component).beforeRender() line: 990
> TmpPage(Component).internalPrepareForRender(boolean) line: 2204
> TmpPage(Page).internalPrepareForRender(boolean) line: 247
> TmpPage(Component).render() line: 2289
> TmpPage(Page).renderPage() line: 1021
>
> This stack trace occurs before the repeating view is populated which would
> render the page stateful and causes the Page to cache that it is stateless.
>
> By the way, I did find a workaround to achieve the desired effect so that's
> not why I brought this up here. I'm just concerned that such erroneous
> computations of the page's stateless state might cause other bugs down the
> road.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
--
regards,
Vineet Semwal
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org
Re: Calling isPageStateless() can mess up the statelessness of a
page
Posted by Bertrand Guay-Paquet <be...@step.polymtl.ca>.
On 10/08/2012 12:12 PM, vineet semwal wrote:
> it might give you wrong result even if you add your component after
> adding all the components because some components foreg. a repeater
> like listview/dataview/gridview add children in onbeforerender so
> isPageStateless() can be assumed to work correctly only after
> onbeforerender
Yes that's exactly what I wanted to say! The repeaters are only
populated in their onBeforeRender() which is executed after onConfigure().
> that caching part is ok imho for isPageStateless() ,actually that
> cached variable is reset in page#onbeforerender which is the another
> reason isPageStateless() should work correctly after onbeforerender
I hadn't noticed that reset in Page#onBeforeRender() so I had a look
since it would contradict my observations.
This is the stack trace when my label's onConfigure() is reached :
TmpPage$1.onConfigure() line: 24 <-- my stateless indicator label;
calls isPageStateless()
TmpPage$1(Component).configure() line: 1028
TmpPage$1(Component).internalBeforeRender() line: 913
TmpPage$1(Component).beforeRender() line: 990
TmpPage(MarkupContainer).onBeforeRenderChildren() line: 1688
TmpPage(Component).onBeforeRender() line: 3830
TmpPage(Page).onBeforeRender() line: 802 <--- line 799 already did
the reset of the cached "stateless" var
TmpPage(Component).internalBeforeRender() line: 922
TmpPage(Component).beforeRender() line: 990
TmpPage(Component).internalPrepareForRender(boolean) line: 2204
TmpPage(Page).internalPrepareForRender(boolean) line: 247
TmpPage(Component).render() line: 2289
TmpPage(Page).renderPage() line: 1021
This stack trace occurs before the repeating view is populated which
would render the page stateful and causes the Page to cache that it is
stateless.
By the way, I did find a workaround to achieve the desired effect so
that's not why I brought this up here. I'm just concerned that such
erroneous computations of the page's stateless state might cause other
bugs down the road.
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org
Re: Calling isPageStateless() can mess up the statelessness of a page
Posted by vineet semwal <vi...@gmail.com>.
it might give you wrong result even if you add your component after
adding all the components because some components foreg. a repeater
like listview/dataview/gridview add children in onbeforerender so
isPageStateless() can be assumed to work correctly only after
onbeforerender
that caching part is ok imho for isPageStateless() ,actually that
cached variable is reset in page#onbeforerender which is the another
reason isPageStateless() should work correctly after onbeforerender
On Fri, Aug 10, 2012 at 7:43 PM, Martin Grigorov <mg...@apache.org> wrote:
> Hi,
>
> The page can become stateful during rendering, as you have noticed.
> There is a code in WebPageRenderer that re-renders the page if it
> change state during the first rendering because otherwise some
> previously rendered links may became broken.
>
> The real problem here is that #isPageStateless() does caching (by
> using Page#stateless variable) and once set it doesn't bother asking
> the components second time.
>
> I see no reason to add restrictions related to the page's lifecycle.
> This wont help.
> The only solution that I see is to remove the caching and make this
> call more expensive. But even in this case your logic wont work.
> It will work only if your label is at the very bottom of the page.
>
> On Fri, Aug 10, 2012 at 4:31 PM, Bertrand Guay-Paquet
> <be...@step.polymtl.ca> wrote:
>> Hi,
>>
>> (Using Wicket 6.0-SNAPSHOT, or 1.5.7)
>>
>> I found a strange behavior when calling Page#isPageStateless(). I have a
>> simple label in my personal wicket debug bar which displays "stateless" when
>> a page is stateless. It works like so:
>>
>> new WebMarkupContainer("statelessMarker") {
>> @Override
>> protected void onConfigure() {
>> super.onConfigure();
>> setVisible(getPage().isPageStateless());
>> }
>> };
>>
>> This worked great until I got by chance a page which was stateless except
>> for ajax links which were children of a repeater. Here is what happens then:
>> 1) onConfigure() is called which calls isPageStateless() and determines the
>> page is stateless
>> 2) onBeforeRender() is executed which populates the repeaters and adds
>> stateful components to the tree
>> 3) Since the page was determined stateless in 1), it stays that way
>> 4) stateful ajax callback links do not work on the page
>>
>> Therefore, it seems that isPageStateless() should never be called before
>> onBeforeRender() is executed or mayhem may ensue. However, after cursory
>> inspection of callers of isPageStateless(), it looks like that is not always
>> the case so I'm not certain.
>>
>> Should this be considered a bug? Should an assertion be made in
>> isPageStateless() that onBeforeRender() was executed?
>>
>> Regards,
>> Bertrand
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>> For additional commands, e-mail: users-help@wicket.apache.org
>>
>
>
>
> --
> Martin Grigorov
> jWeekend
> Training, Consulting, Development
> http://jWeekend.com
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
--
regards,
Vineet Semwal
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org
Re: Calling isPageStateless() can mess up the statelessness of a page
Posted by Martin Grigorov <mg...@apache.org>.
Hi,
The page can become stateful during rendering, as you have noticed.
There is a code in WebPageRenderer that re-renders the page if it
change state during the first rendering because otherwise some
previously rendered links may became broken.
The real problem here is that #isPageStateless() does caching (by
using Page#stateless variable) and once set it doesn't bother asking
the components second time.
I see no reason to add restrictions related to the page's lifecycle.
This wont help.
The only solution that I see is to remove the caching and make this
call more expensive. But even in this case your logic wont work.
It will work only if your label is at the very bottom of the page.
On Fri, Aug 10, 2012 at 4:31 PM, Bertrand Guay-Paquet
<be...@step.polymtl.ca> wrote:
> Hi,
>
> (Using Wicket 6.0-SNAPSHOT, or 1.5.7)
>
> I found a strange behavior when calling Page#isPageStateless(). I have a
> simple label in my personal wicket debug bar which displays "stateless" when
> a page is stateless. It works like so:
>
> new WebMarkupContainer("statelessMarker") {
> @Override
> protected void onConfigure() {
> super.onConfigure();
> setVisible(getPage().isPageStateless());
> }
> };
>
> This worked great until I got by chance a page which was stateless except
> for ajax links which were children of a repeater. Here is what happens then:
> 1) onConfigure() is called which calls isPageStateless() and determines the
> page is stateless
> 2) onBeforeRender() is executed which populates the repeaters and adds
> stateful components to the tree
> 3) Since the page was determined stateless in 1), it stays that way
> 4) stateful ajax callback links do not work on the page
>
> Therefore, it seems that isPageStateless() should never be called before
> onBeforeRender() is executed or mayhem may ensue. However, after cursory
> inspection of callers of isPageStateless(), it looks like that is not always
> the case so I'm not certain.
>
> Should this be considered a bug? Should an assertion be made in
> isPageStateless() that onBeforeRender() was executed?
>
> Regards,
> Bertrand
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
--
Martin Grigorov
jWeekend
Training, Consulting, Development
http://jWeekend.com
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org
Re: Calling isPageStateless() can mess up the statelessness of a page
Posted by vineet semwal <vi...@gmail.com>.
currently i think you can do by keeping some boolean variable that you
can populate after page#onbeforerender
and override your desired component's isVisible() {return my_boolean ;}
On Fri, Aug 10, 2012 at 7:01 PM, Bertrand Guay-Paquet
<be...@step.polymtl.ca> wrote:
> Hi,
>
> (Using Wicket 6.0-SNAPSHOT, or 1.5.7)
>
> I found a strange behavior when calling Page#isPageStateless(). I have a
> simple label in my personal wicket debug bar which displays "stateless" when
> a page is stateless. It works like so:
>
> new WebMarkupContainer("statelessMarker") {
> @Override
> protected void onConfigure() {
> super.onConfigure();
> setVisible(getPage().isPageStateless());
> }
> };
>
> This worked great until I got by chance a page which was stateless except
> for ajax links which were children of a repeater. Here is what happens then:
> 1) onConfigure() is called which calls isPageStateless() and determines the
> page is stateless
> 2) onBeforeRender() is executed which populates the repeaters and adds
> stateful components to the tree
> 3) Since the page was determined stateless in 1), it stays that way
> 4) stateful ajax callback links do not work on the page
>
> Therefore, it seems that isPageStateless() should never be called before
> onBeforeRender() is executed or mayhem may ensue. However, after cursory
> inspection of callers of isPageStateless(), it looks like that is not always
> the case so I'm not certain.
>
> Should this be considered a bug? Should an assertion be made in
> isPageStateless() that onBeforeRender() was executed?
>
> Regards,
> Bertrand
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
--
regards,
Vineet Semwal
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org