On Mon, Feb 10, 2014 at 9:43 AM, Igor Vaynberg <igor.vaynb...@gmail.com>wrote:
> i just pushed my new idea into sandbox/component-queueing-2 > > the way this works now is instead of doing it in onInitialize() and in > onConfigure() and all the other places dequeuing now works progressively. > upon a change (container.queue() or component.add()) a dequeue will be > tried. > > it even works well with resolved components like enclosures. for such > components the markup of page/panel is traversed in onInitialize() and all > auto components are placed into the queue. later as components are > added/queued these components will be placed into the correct place in the > hierarchy. if queue() is used children of these components will be placed > under them in correct hierarchy place. this is a big win for using queueing > over adding. > > repeaters also work. the repeater items themselves have to be added to the > repeater, but item's children can be queued. this is not a problem since > items are mostly added by framework classes. > > Borders do not yet work mainly because i havent tried to make them work. > the tricky part there is to keep the border and BorderBody queues separate. > I've added some code to support it but it needs more work. See my response to the commit notification email of my changes. Also we have BorderBehavior and BorderPanel. I think (almost) no one uses those but they exist. > > InlineEnclosures do not yet work because the code for figuring out the > value of the child attribute is really convoluted for the simple thing its > supposed to do and i didnt bother parsing it. Should be very similar to how > EnclosureHandler works. > Done. > > the performance is good. there is ComponentQueueingPerformanceTest with a > disabled test. give it a go and let me know the results. on my box queuing > had under 10% overhead, which is acceptable. I also have some ideas on how > to optimize that further by trading cpu for a bit more memory, but not sure > In my branch on this topic I used HashMap instead of array. The lookup is faster. Not sure how much memory overhead there is. > if its needed since the overhead is low and because its only present when > queuing is used. also the measurements are not too accurate because most of > the time is spent initializing and tearing down a WicketTester instance. > > memory overhead is also low, two slots (one of which can/should be > converted to a flag) are added to MarkupContainer. > > see ComponentQueuing test for some examples. i would appreciate some help > getting Border and InlineEnclosure working if someone has time. > > look over this and lets discuss if/when we should merge it into master. > > -igor > > > > On Fri, Jan 31, 2014 at 1:17 AM, Martin Grigorov <mgrigo...@apache.org > >wrote: > > > Hi Sven, > > > > The component tree rebuilding adds CPU time :-| > > I guess most of the applications would still prefer the current approach > > with the manual construction of the tree in Java land. > > > > Even worse - the rebuilding is needed few times: > > - once before calling Page#onInitialize() so all enqueued children in the > > constructors will have their correct parent and thus their > #onInitialize() > > will be called too > > - after Page#onInitialize() because the application may enqueue more > > children in any Component#onInitialize() > > - finally during rendering because a component may get enqueued in > > #onConfigure > > > > Component tree re-arranging is something important too. I have listed it > as > > task #2 in my first mail in this thread. > > At the moment the children of an enclosure appear at their correct > position > > only with when they are enqueued. More work is needed to support when > they > > are added (as in any existing application at the moment). > > > > I'm wondering what idea Igor has. We need to fix the Eclipse settings > state > > soon. > > > > On Thu, Jan 30, 2014 at 6:36 PM, Sven Meier <s...@meiers.net> wrote: > > > > > Hi Martin, > > > > > > if we want markup driven component trees in Wicket, we have to decide > > > whether this is optional or always supported. > > > > > > Currently it's a mix of both: a developer might enqueue components, but > > > they are not used because no listener or behavior rebuilds the > container. > > > > > > As it is now, we could equally well make it explicit, i.e. move > > everything > > > into a temporary behavior, that keeps the enqueued components until it > is > > > able to rebuild the container: > > > > > > RebuildBehavior#rebuild(Component... cs); > > > > > > ComponentA a = new ComponentA("a"); > > > ComponentB b = new ComponentB("b"); > > > ComponentC c = new ComponentC("c"); > > > add(rebuild(a, b, c)); > > > > > > What I dislike about an optional solution though: It doesn't solve our > > > issues with non-auto components inside of enclosures. I would prefer a > > > solution which takes care of these too, i.e. it would be able to > > re-arrange > > > already added components. > > > > > > > > > Regards > > > Sven > > > > > > > > > On 01/27/2014 02:14 PM, Martin Grigorov wrote: > > > > > >> I am suspending my work on this because I think there is not enough > > >> interest in this feature at the moment. > > >> > > >> Martin Grigorov > > >> Wicket Training and Consulting > > >> > > >> > > >> On Mon, Jan 27, 2014 at 10:07 AM, Martin Grigorov < > mgrigo...@apache.org > > >> >wrote: > > >> > > >> Reading the archives for Igor's work on "component queueing" I see > > >>> > > >>> Igor Vaynberg<https://issues.apache.org/jira/secure/ > > >>> ViewProfile.jspa?name=ivaynberg> added > > >>> > > >>> a comment - 09/Jul/11 23:39 > > >>> > > >>> @Juergen, right now your tests only test for rendering, but they > should > > >>> also test that before queued component's oninitialize is called the > > >>> component is already a child of the correct parent. > > >>> > > >>> https://issues.apache.org/jira/browse/WICKET-3335 > > >>> > > >>> > > >>> This means that > > >>> org.apache.wicket.application.IComponentInitializationListener cannot > > be > > >>> used. The tree (re)building should happen *before *components' > > >>> > > >>> #onInitialize() and .IComponentInitializationListener#onInitialize() > is > > >>> called *after*. > > >>> > > >>> Martin Grigorov > > >>> Wicket Training and Consulting > > >>> > > >>> > > >>> On Fri, Jan 24, 2014 at 2:22 PM, Martin Grigorov < > mgrigo...@apache.org > > >>> >wrote: > > >>> > > >>> I've added alternative ways to use MarkupDrivenComponentTreeBuilder: > > >>>> - with org.apache.wicket.MarkupDrivenTreeInitializionListener > > >>>> - with > org.apache.wicket.MarkupDrivenComponentTreeBehavior#onConfigure > > >>>> > > >>>> Both of them do not check the configuration setting whether markup > > >>>> driven > > >>>> tree construction is enabled for now. > > >>>> > > >>>> The approach with MarkupDrivenTreeInitializionListener works the > same > > >>>> way > > >>>> as the "inlined" version. The component tree rebuild is activated > > >>>> *after* > > >>>> all Component#onInitialize(). > > >>>> > > >>>> The approach with MarkupDrivenComponentTreeBehavior uses > > >>>> #onConfigure(). > > >>>> Here I had to change Enclosure class - the child component resolving > > >>>> should > > >>>> be done as late as possible just before the rendering phase starts. > > >>>> > > >>>> Martin Grigorov > > >>>> Wicket Training and Consulting > > >>>> > > >>>> > > >>>> On Fri, Jan 24, 2014 at 11:47 AM, Martin Grigorov < > > mgrigo...@apache.org > > >>>> >wrote: > > >>>> > > >>>> OK, the new impl is committed. > > >>>>> Now MarkupContainer has #enqueue(Component...) method that adds > > >>>>> components into a list. > > >>>>> Later org.apache.wicket.ComponentTreeBuilder#rebuild() uses the > list, > > >>>>> and finally the list is null-yfied in #onDetach() so it is not > > >>>>> serialized > > >>>>> and not available for the next requests. I guess the null-yfing can > > be > > >>>>> done > > >>>>> earlier so even the first request have the extra bytes after the > > >>>>> rebuild of > > >>>>> the tree. > > >>>>> > > >>>>> No need of @Auto anymore. > > >>>>> > > >>>>> Martin Grigorov > > >>>>> Wicket Training and Consulting > > >>>>> > > >>>>> > > >>>>> On Fri, Jan 24, 2014 at 10:39 AM, Martin Grigorov < > > >>>>> mgrigo...@apache.org>wrote: > > >>>>> > > >>>>> > > >>>>>> On Fri, Jan 24, 2014 at 9:48 AM, Sven Meier <s...@meiers.net> > > wrote: > > >>>>>> > > >>>>>> per-component basis - yes, as I explained earlier this is > possible > > >>>>>>>> > > >>>>>>> with the current impl > > >>>>>>> > > >>>>>>> I must have missed that. Is there an example in the branch? > > >>>>>>> > > >>>>>>> See > > >>>>>> https://github.com/apache/wicket/blob/markup-driven- > > >>>>>> component-tree/wicket-core/src/main/java/org/apache/ > > >>>>>> wicket/MarkupContainer.java?source=c#L1886 > > >>>>>> There is no test yet. > > >>>>>> > > >>>>>> > > >>>>>> I don't understand why there's need for an @Auto annotation. Why > > >>>>>>> would > > >>>>>>> some components be annotated and some not? > > >>>>>>> > > >>>>>> > > >>>>>> The annotation was needed to be able to find the component faster. > > >>>>>> I.e. check only annotated fields. If @Auto(id=...) then use the id > > to > > >>>>>> match against the component tag id. > > >>>>>> > > >>>>>> But with my new idea, the one that will solve the issue with the > > extra > > >>>>>> bytes, this won't be needed anymore. > > >>>>>> Stay tuned. > > >>>>>> > > >>>>>> > > >>>>>> > > >>>>>>> behaviors don't have hooks for onInitialize() > > >>>>>>> It could be done in #onConfigue(), that's early enough. > > >>>>>>> > > >>>>>> > > >>>>>> The problem is that it is called for each request. > > >>>>>> For now I think there is no need to rebuild the component tree for > > >>>>>> each > > >>>>>> request, so we will have to use a guard (e.g. boolean field in the > > >>>>>> component). > > >>>>>> I will consider it. > > >>>>>> > > >>>>>> > > >>>>>> > > >>>>>>> Additionally I think using Behavior will add a bit more bytes > to > > >>>>>>> each > > >>>>>>> > > >>>>>>>> component than the current solution > > >>>>>>>> > > >>>>>>>> I don't think that is a problem: IMHO it's important to make > this > > >>>>>>> feature optional, so when users don't use it then they do not > pay a > > >>>>>>> price. > > >>>>>>> > > >>>>>>> Regards > > >>>>>>> Sven > > >>>>>>> > > >>>>>>> > > >>>>>>> > > >>>>>>> > > >>>>>>> On 01/24/2014 06:35 AM, Martin Grigorov wrote: > > >>>>>>> > > >>>>>>> On Fri, Jan 24, 2014 at 12:04 AM, Sven Meier <s...@meiers.net> > > >>>>>>>> wrote: > > >>>>>>>> > > >>>>>>>> Hi, > > >>>>>>>> > > >>>>>>>>> I don't think we're heading the right direction with this and I > > >>>>>>>>> wouldn't > > >>>>>>>>> advertise it as anything yet. > > >>>>>>>>> > > >>>>>>>>> I'd like to advertise it anyhow now just to have more people > > >>>>>>>>> > > >>>>>>>> feeding me > > >>>>>>>> with stoppers, as you and Igor do. Thanks! :-) > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> There are more questions to come but here is one upfront: > > >>>>>>>> > > >>>>>>>>> > > >>>>>>>>> And it is configurable, by default disabled. > > >>>>>>>>> As Igor has written, this does not work with component > libraries > > >>>>>>>>> which > > >>>>>>>>> depend on the new feature. > > >>>>>>>>> Couldn't this feature be enabled/disabled on a per-component > > basis? > > >>>>>>>>> Why > > >>>>>>>>> not make it a behavior that you can attach to components if you > > >>>>>>>>> want > > >>>>>>>>> to use > > >>>>>>>>> automatic resolving/rearranging of its children? > > >>>>>>>>> > > >>>>>>>>> - per-component basis - yes, as I explained earlier this is > > >>>>>>>>> > > >>>>>>>> possible with > > >>>>>>>> the current impl > > >>>>>>>> - behaviors don't have hooks for onInitialize() > > >>>>>>>> After Igor's feedback I think onAfterInitialize() is what is > > needed, > > >>>>>>>> so > > >>>>>>>> apps can use onInitialize() as a complement to the constructor > > >>>>>>>> Additionally I think using Behavior will add a bit more bytes to > > >>>>>>>> each > > >>>>>>>> component than the current solution > > >>>>>>>> > > >>>>>>>> > > >>>>>>>> Regards > > >>>>>>>> > > >>>>>>>>> Sven > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> > > >>>>>>>>> On 01/23/2014 05:20 PM, Martin Grigorov wrote: > > >>>>>>>>> > > >>>>>>>>> Once the markup driven construction is done (just before > > >>>>>>>>> > > >>>>>>>>>> onInitialize()) > > >>>>>>>>>> the application will have to use the old good > > >>>>>>>>>> add()/addOrReplace(). > > >>>>>>>>>> > > >>>>>>>>>> The components are already in the MarkupContainer#children > data > > >>>>>>>>>> structure. > > >>>>>>>>>> So each field will add extra 8 bytes on 64bit machine (or 4 > > bytes > > >>>>>>>>>> with > > >>>>>>>>>> CompressedOops enabled). > > >>>>>>>>>> Serialization is the same - the object is written once, with > > >>>>>>>>>> several > > >>>>>>>>>> pointers. > > >>>>>>>>>> > > >>>>>>>>>> I am also not fully sure in the approach but I am > experimenting > > >>>>>>>>>> and > > >>>>>>>>>> so far > > >>>>>>>>>> it works well. > > >>>>>>>>>> And it is configurable, by default disabled. > > >>>>>>>>>> We can advertise it as experimental ?! > > >>>>>>>>>> > > >>>>>>>>>> I will add more use cases/tests soon. > > >>>>>>>>>> And caching for the reflection stuff. > > >>>>>>>>>> > > >>>>>>>>>> > > >>>>>>>>>> On Thu, Jan 23, 2014 at 6:09 PM, Igor Vaynberg < > > >>>>>>>>>> igor.vaynb...@gmail.com> > > >>>>>>>>>> wrote: > > >>>>>>>>>> > > >>>>>>>>>> what about components added in onInitialize() or on > > >>>>>>>>>> onConfigure()? > > >>>>>>>>>> > > >>>>>>>>>> this will also lead to a higher memory/serialization space > > usage > > >>>>>>>>>>> since > > >>>>>>>>>>> by default you need a field to store the component ref. > > >>>>>>>>>>> > > >>>>>>>>>>> not sure its worth doing it this way... > > >>>>>>>>>>> > > >>>>>>>>>>> -igor > > >>>>>>>>>>> > > >>>>>>>>>>> > > >>>>>>>>>>> On Wed, Jan 22, 2014 at 12:12 PM, Martin Grigorov < > > >>>>>>>>>>> mgrigo...@apache.org> > > >>>>>>>>>>> wrote: > > >>>>>>>>>>> > > >>>>>>>>>>> Hi, > > >>>>>>>>>>> > > >>>>>>>>>>>> Recently Fridolin Jackstadt shared his approach to > "autowire" > > >>>>>>>>>>>> components > > >>>>>>>>>>>> > > >>>>>>>>>>>> - > > >>>>>>>>>>>> > > >>>>>>>>>>> https://github.com/wicket-acc/wicket-autowire. > > >>>>>>>>>>> > > >>>>>>>>>>>> I believe this approach can solve two issues: > > >>>>>>>>>>>> - duplicate construction of the component tree - once in the > > >>>>>>>>>>>> markup and > > >>>>>>>>>>>> second time in Java code > > >>>>>>>>>>>> - auto components available only in the render phase > > >>>>>>>>>>>> > > >>>>>>>>>>>> Here is how I see it: > > >>>>>>>>>>>> > > >>>>>>>>>>>> Any MarkupContainer that wants to use markup-driven-tree > must > > >>>>>>>>>>>> declare > > >>>>>>>>>>>> the > > >>>>>>>>>>>> components as member fields: > > >>>>>>>>>>>> > > >>>>>>>>>>>> private SomeComponent aComponent; > > >>>>>>>>>>>> > > >>>>>>>>>>>> These fields will be instantiated like any other component > in > > >>>>>>>>>>>> Wicket: > > >>>>>>>>>>>> > > >>>>>>>>>>>> aComponent = new SomeComponent(id, ...); > > >>>>>>>>>>>> > > >>>>>>>>>>>> The new thing is that they *won't* be added to a parent > > >>>>>>>>>>>> component > > >>>>>>>>>>>> explicitly/manually. > > >>>>>>>>>>>> > > >>>>>>>>>>>> On Page#onInitialize() the first thing to do it to walk over > > the > > >>>>>>>>>>>> > > >>>>>>>>>>>> component > > >>>>>>>>>>>> > > >>>>>>>>>>> tree from the page's markup (just like the walk in the > > >>>>>>>>>>> rendering > > >>>>>>>>>>> > > >>>>>>>>>>>> related > > >>>>>>>>>>>> code) and resolve the missing bits. > > >>>>>>>>>>>> I.e. while walking thru the markup tree we will check the > Java > > >>>>>>>>>>>> component > > >>>>>>>>>>>> tree (container.get(tagId)). If there is a miss then we > search > > >>>>>>>>>>>> for a > > >>>>>>>>>>>> > > >>>>>>>>>>>> member > > >>>>>>>>>>>> > > >>>>>>>>>>> field that is a component with the same id in the current > > >>>>>>>>>>> > > >>>>>>>>>>>> MarkupContainer, > > >>>>>>>>>>>> > > >>>>>>>>>>> its (Java) super classes and finally in its (Wicket) parent > > >>>>>>>>>>> > > >>>>>>>>>>>> classes. > > >>>>>>>>>>>> > > >>>>>>>>>>>> This will solve issue #1 (identical trees in Java and > markup) > > >>>>>>>>>>>> (P.S. Fridolin's code uses @AutoComponent annotation that > > >>>>>>>>>>>> facilitates > > >>>>>>>>>>>> searching by component id, but will duplicate the > declaration > > of > > >>>>>>>>>>>> the id > > >>>>>>>>>>>> - > > >>>>>>>>>>>> once in the annotation and second time in 'new > > MyComponent(ID). > > >>>>>>>>>>>> This is > > >>>>>>>>>>>> > > >>>>>>>>>>>> an > > >>>>>>>>>>>> > > >>>>>>>>>>> implementation detail.) > > >>>>>>>>>>> > > >>>>>>>>>>>> > > >>>>>>>>>>>> The second part is not less hard - during the walk over the > > >>>>>>>>>>>> markup tree > > >>>>>>>>>>>> when an autocomponent (e.g. enclosure) is seen Wicket will > use > > >>>>>>>>>>>> the > > >>>>>>>>>>>> registered IComponentResolvers to create the Java component > > and > > >>>>>>>>>>>> insert > > >>>>>>>>>>>> it > > >>>>>>>>>>>> in the Java tree. > > >>>>>>>>>>>> The tricky part here is that any manually added components > > (like > > >>>>>>>>>>>> in > > >>>>>>>>>>>> > > >>>>>>>>>>>> Wicket > > >>>>>>>>>>>> > > >>>>>>>>>>> 6.x) to the parent of the autocomponent should be moved > into > > >>>>>>>>>>> the > > >>>>>>>>>>> > > >>>>>>>>>>>> autocomponent. > > >>>>>>>>>>>> For example: > > >>>>>>>>>>>> > > >>>>>>>>>>>> <div wicket:id="a"> > > >>>>>>>>>>>> <wicket:enclosure child="b"> > > >>>>>>>>>>>> <span wicket:id="b"></span> > > >>>>>>>>>>>> <span wicket:id="c"></span> > > >>>>>>>>>>>> </wicket:enclosure> > > >>>>>>>>>>>> </div> > > >>>>>>>>>>>> > > >>>>>>>>>>>> If 'b' and 'c' are added manually to 'a' in the > application's > > >>>>>>>>>>>> Java code: > > >>>>>>>>>>>> (a (b,c)) > > >>>>>>>>>>>> > > >>>>>>>>>>>> then after the "resolving phase" the tree will be: > > >>>>>>>>>>>> > > >>>>>>>>>>>> a (enclosure(b, c)) > > >>>>>>>>>>>> > > >>>>>>>>>>>> so b.getParent() in onInitialize() and later will return the > > >>>>>>>>>>>> Enclosure, > > >>>>>>>>>>>> > > >>>>>>>>>>>> not > > >>>>>>>>>>>> > > >>>>>>>>>>> 'a'. > > >>>>>>>>>>> > > >>>>>>>>>>>> > > >>>>>>>>>>>> I don't know very well the MarkupStream APIs but I think all > > >>>>>>>>>>>> this > > >>>>>>>>>>>> should > > >>>>>>>>>>>> > > >>>>>>>>>>>> be > > >>>>>>>>>>>> > > >>>>>>>>>>> possible. > > >>>>>>>>>>> > > >>>>>>>>>>>> WDYT about this approach ? > > >>>>>>>>>>>> > > >>>>>>>>>>>> > > >>>>>>>>>>>> Martin Grigorov > > >>>>>>>>>>>> Wicket Training and Consulting > > >>>>>>>>>>>> > > >>>>>>>>>>>> > > >>>>>>>>>>>> > > > > > >