Can we use some creative readResolve/writeReplace logic to serialize
the page references?  So, when you write out the page reference, you
spit out one of Igor's Pageid objects?  Then, on the readResolve()
method, it will use the page id to lookup the actual page reference.

On Mon, Mar 2, 2009 at 6:17 PM, Matej Knopp <[email protected]> wrote:
> By bad practice I meant unnecessary or "accidental" page references.
> They don't bring you much apart from performance degradation and if
> you are lucky nice fat stacktrace :)
>
> We might be able to detect page reference, that should be pretty
> simple - i.e. override page#writeObject and check if there is another
> page being serialized in this thread. On the other hand, the current
> code also seemed pretty simple at the beginning...
>
> -Matej
>
> On Tue, Mar 3, 2009 at 12:13 AM, Igor Vaynberg <[email protected]> 
> wrote:
>> i already built something similar to the page.getreference() Matej is
>> talking about. see PageId,  Page#getPageId(), and
>> RequestCycle#urlFor(PageId). this is very useful for building
>> breadcrumbs as you dont have to pass a stack of pages around.
>>
>> generally i agree, supporting page references is a pita. whether or
>> not it should be considered a bad practice i dont claim to know, but
>> it is definitely causing as headaches. i would remove the specialized
>> serialization code, and if we can detect a page reference from one
>> page to another during serialization i would log a warning.
>>
>> -igor
>>
>> On Mon, Mar 2, 2009 at 2:38 PM, Matej Knopp <[email protected]> wrote:
>>> Hi,
>>>
>>> more perceptive people have probably noticed that there is some really
>>> obscure page serialization related code in Wicket. What it is supposed
>>> to do is to make sure that when PageA holds reference to pageB, pageA
>>> and pageB get serialized separately and when pageA is deserialized,
>>> pageB is loaded also separately. So that the two pages would not be
>>> serialized in one piece.
>>>
>>> Unfortunately this is not as simple as it sounds, because pageB can
>>> hold reference to pageC which in turn can have an object that is
>>> anonymous class from pageA, so we need to deal with circular
>>> references, implicit references and lot of other nasty things. The
>>> bottom line is, this causes many weird serialization related bugs that
>>> are extremely difficult to fix. The code is also big pain to maintain.
>>>
>>> Simply put, passing references between pages and page serialization
>>> don't mix nicely. We need page serialization because it really helps
>>> scalability and memory consumption so I think it might be time to
>>> "deprecate" page references.
>>>
>>> Of course there would be a simple alternative.
>>>
>>> I.e. instead of
>>>
>>> class PageA ...
>>> {
>>>   ...
>>>   public void doSomething() {
>>>      setResponsePage(new PageB(this));
>>>   }
>>> }
>>>
>>> it would be
>>>
>>> class PageA ...
>>> {
>>>   ...
>>>   public void doSomething() {
>>>      setResponsePage(new PageB(this.getReference()));
>>>   }
>>> }
>>>
>>> and
>>>
>>> class PageB ...
>>> {
>>>   public PageB(final PageReference<PageA> pageA)
>>>   {
>>>      // to get the actual instance if you need it
>>>      PageA a = pageA.get();
>>>
>>>     // or use the reference directly
>>>     add(new PageLink("back", pageA);
>>>
>>>     // or even like this
>>>     add(new Link("back2") { public void onClick() {
>>> getRequestCycle().setResponsePage(pageA) } });
>>>   }
>>> }
>>>
>>> Also this would help the performance, because if PageB only uses pageA
>>> to return back (which is IMHO the most common case) it would only
>>> require tiny PageReference object instead of entire page.
>>>
>>> -Matej
>>>
>>
>

Reply via email to