#1 you would need large(r) buffers (which might get an issue depending on your concrete needs) #2 furthermore, you can't use "early flush before the html-body" -> you benefit in the first step, but it impacts further optimizations #3 if you wait in the callback anyway, you can just do the parallel loading (or the delegation to parallel loading) there - that just won't work (easily) with a producer-centric style #4 page-beans which delegate to other beans (which do almost the same as your producers) vs. a producers-only style is imo a choice which depends a lot on your application (+ el-resolvers of di-frameworks can just provide optimizations if you have as few diff. names as possible - per page-request).
based on what i've seen so far in a "typical" jsf-application, the benefit you get with such a parallelization isn't that huge - given that you can't benefit from other possible optimizations. regards, gerhard 2016-04-09 11:59 GMT+02:00 Christian Beikov <[email protected]>: > Wouldn't setting the buffer size to an appropriate size deal with the > problem with redirecting on an error? > We could also await all async loads before exiting the phase listener, > thus having loaded everything before the rendering starts. > > Caching the data in a page bean is of course a possibility, but I moved > away from this kind of style because then you have to spread all your data > reloads in every possible action method. I find it nicer to define a scope > for a producer that most of the time is a perfect fit and if necessary, I > can still invalidate it. Having referenced producers now makes it easy to > achieve a speedup without having to do anything manually(except for > annotating the safe producer methods with the interceptor annotation). > > Mit freundlichen Grüßen, > ------------------------------------------------------------------------ > *Christian Beikov* > Am 09.04.2016 um 11:23 schrieb Gerhard Petracek: > >> 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* >>>>>>> >>>>>>> >>>>>>> >>>>>>> >
