deltaspike-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Gerhard Petracek <gerhard.petra...@gmail.com>
Subject Re: Context capturing and JSF Parallel-Preloading
Date Sat, 09 Apr 2016 10:34:19 GMT
#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 <christian.beikov@gmail.com>:

> 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 <christian.beikov@gmail.com>:
>>
>> 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 <christian.beikov@gmail.com
>>>> >:
>>>>
>>>> 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 <
>>>>>> christian.beikov@gmail.com
>>>>>>
>>>>>>> :
>>>>>>>
>>>>>> 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*
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message