hi @ all, i considered something similar some days ago. (the benefit of @Futureable in combination with @PreRenderView callbacks.) the main issue is that it isn't a nice idea to start with the rendering before all data was loaded (and you know that you don't need to render a diff. page - like an error-page).
usually it's enough to cache the loaded data in a page-bean (just load multiple parts in parallel - e.g. in a @PreRenderView callback). regards, gerhard 2016-04-09 9:55 GMT+02:00 Christian Beikov <[email protected]>: > I extract the "bindings" map of every UIComponent and analyze all "simple" > expressions further. > Simple expression are ones that don't contain a dot in the expression > string. Since named producers will always have a simple name this will > filter out most of the unnecessary expressions. Then I check whether the > last few expressions resolve to beans and if so, I check if the bean is > annotated with the @PreloadingSafe annotation. If all that is true, then > the bean can be preloaded. > > You are right that this might be a considerable overhead. I will have to > check what the performance impact of that strategy is. Still I think that > since it's nicely cacheable, it will only add a few milliseconds (if at > all) the first time the tree is traversed. > > What do you think about the strategy? Do you have any ideas how I could > improve it? > > Mit freundlichen Grüßen, > ------------------------------------------------------------------------ > *Christian Beikov* > Am 09.04.2016 um 09:44 schrieb Thomas Andraschko: > >> The traversal itself is ok but how do you analyze the expression? I think >> you have to do it for every component and every value attribute. Thats >> something i would like to avoid. >> >> 2016-04-09 9:38 GMT+02:00 Christian Beikov <[email protected]>: >> >> Hello Thomas, >>> >>> well scanning the tree shouldn't be such a big problem I guess since the >>> JSF lifecycle already traverses the tree multiple times. Doing it another >>> time shouldn't do that much damage I think, especially because the >>> traversal would be aware of the client ids that should be rendered in an >>> ajax request. I also think that it is fairly easy to optimize since I >>> could >>> cache the preloadable EL-Expressions along with the client ids that they >>> belong to for a view. So this would only require a traversal once. >>> >>> The whole idea and use case for which I am implementing this was to make >>> the preloading in an automatic fashion without the need to touch the >>> views. >>> Having a preload tag would be definitely another way, but I would like to >>> first test the performance impact of scanning the expressions. The >>> preload >>> tag would also be problematic in the ajax use case since it will probably >>> be located outside of the components that are rendered. >>> >>> I was also thinking about collecting statistics for the methods that are >>> used and try to start preloading opportunistically based on that data. >>> >>> Mit freundlichen Grüßen, >>> ------------------------------------------------------------------------ >>> *Christian Beikov* >>> Am 09.04.2016 um 09:18 schrieb Thomas Andraschko: >>> >>> Hi Christian, >>>> >>>> basically thats an interesting idea, just not sure if we could implement >>>> it >>>> in a nicer way. >>>> I think scanning the component tree and analyzing every EL expression >>>> feels >>>> a little risky and slow. >>>> >>>> Using a bytecode library isn't the problem in the JSF module, we already >>>> use there our proxy module. >>>> >>>> Couldn't we just reuse our @Futureable? >>>> Sure, the handling in the UI would be little bit different >>>> (supplierNames >>>> vs supplierNames.get()) but Future should work, right? >>>> >>>> Regards, >>>> Thomas >>>> >>>> >>>> >>>> 2016-04-09 8:06 GMT+02:00 Christian Beikov <[email protected] >>>> >: >>>> >>>> Hello, >>>> >>>>> I am implementing some POCs for parallel preloading of named producer >>>>> methods and think I have a working prototype. >>>>> I wanted to know if you are interested in including this into >>>>> Deltaspike >>>>> and if so, how I should contribute it. >>>>> >>>>> It is separated into two parts, one is the context capturing in one >>>>> thread >>>>> and the possibility to start these contexts for a new thread. >>>>> The other part is a phase listener that scans the component tree for >>>>> UEL-Expressions that evaluate to a named producer method which is >>>>> annotated >>>>> with a special interceptor annotation(@PreloadingSafe). These producers >>>>> are >>>>> then invoked in the before render response phase in parallel. This >>>>> currently works by creating a proxy from the returned interface. The >>>>> invocation handler behind it, just delegates to the result of the >>>>> future >>>>> that was received by submitting the producer method to an >>>>> ExecutorService. >>>>> It would be nice if this could also work with non-interface types but >>>>> that >>>>> would require some bytecode library which I didn't want to introduce >>>>> yet. >>>>> >>>>> Here some example code: >>>>> >>>>> public class SomeProducerBean { >>>>> >>>>> @PreloadingSafe >>>>> @Named >>>>> @Produces >>>>> @RequestScoped >>>>> public List<String> getSupplierNames() { /* Some DB call */ } >>>>> >>>>> } >>>>> >>>>> <html> >>>>> ... >>>>> <ui:repeat value="#{supplierNames}" var="supplName"> >>>>> #{supplName} >>>>> <ui:repeat> >>>>> ... >>>>> </html> >>>>> >>>>> So the rendering until it reaches the ui:repeat runs in parallel to the >>>>> preloading of the supplier names. When the JSF-Component tries the >>>>> evaluate >>>>> the expression it might need to block. Also note that other expressions >>>>> will still be evaluated in parallel even if one blocks so this can be a >>>>> huge boost for performance. >>>>> >>>>> It's not fully tested yet. The easy case works but I haven't tested >>>>> more >>>>> complex scenarios or possible threading issues yet. >>>>> >>>>> What do you say? >>>>> >>>>> -- >>>>> >>>>> Mit freundlichen Grüßen, >>>>> >>>>> ------------------------------------------------------------------------ >>>>> *Christian Beikov* >>>>> >>>>> >>>>> >
