Return-Path: X-Original-To: apmail-deltaspike-users-archive@www.apache.org Delivered-To: apmail-deltaspike-users-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 8896E19C8E for ; Mon, 11 Apr 2016 12:11:40 +0000 (UTC) Received: (qmail 47825 invoked by uid 500); 11 Apr 2016 12:11:40 -0000 Delivered-To: apmail-deltaspike-users-archive@deltaspike.apache.org Received: (qmail 47789 invoked by uid 500); 11 Apr 2016 12:11:40 -0000 Mailing-List: contact users-help@deltaspike.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: users@deltaspike.apache.org Delivered-To: mailing list users@deltaspike.apache.org Received: (qmail 47777 invoked by uid 99); 11 Apr 2016 12:11:40 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd2-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 11 Apr 2016 12:11:40 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd2-us-west.apache.org (ASF Mail Server at spamd2-us-west.apache.org) with ESMTP id 963331A05AF for ; Mon, 11 Apr 2016 12:11:39 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd2-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: 1.179 X-Spam-Level: * X-Spam-Status: No, score=1.179 tagged_above=-999 required=6.31 tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=2, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_PASS=-0.001] autolearn=disabled Authentication-Results: spamd2-us-west.apache.org (amavisd-new); dkim=pass (2048-bit key) header.d=gmail.com Received: from mx2-lw-us.apache.org ([10.40.0.8]) by localhost (spamd2-us-west.apache.org [10.40.0.9]) (amavisd-new, port 10024) with ESMTP id i7B5GGEzpD-C for ; Mon, 11 Apr 2016 12:11:36 +0000 (UTC) Received: from mail-wm0-f46.google.com (mail-wm0-f46.google.com [74.125.82.46]) by mx2-lw-us.apache.org (ASF Mail Server at mx2-lw-us.apache.org) with ESMTPS id BE8695F1BE for ; Mon, 11 Apr 2016 12:11:35 +0000 (UTC) Received: by mail-wm0-f46.google.com with SMTP id a140so10070335wma.0 for ; Mon, 11 Apr 2016 05:11:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to; bh=Hoq6IVxBBND9IDepNTpYfk3C6NMKmON48q76hvtHAj0=; b=X0AShOxv+1v5XltPo1IlZUE7opOCiQxTZmzkj0Y+kUKoo3PdGap0ugZ6DQx27nLl6g k/qafgOTbP6/gQgI4AS48kSW3bzSqYMZst16sWQR8Db8JJ3Vk+7ojRQc1qLQrGXt3468 hOh3lsDnBMltotSrCmVjluoKf+p9wBZWCnJUD4i6MU1waiySiZioyAuCu5ONxoLKN2cj wxcoNij90ukZxd+pXFopdve8XicAj9E1y3C/I46l9CTsEO8ZZncCZJr3ZZq7/YQo0seX iYi+E+KRHkHNF4jyaxauHcjAiQCWiRwzStrmk99qzVHVx/4gWhKTEL+jvKKJ5gtuuaL4 /8Mg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to; bh=Hoq6IVxBBND9IDepNTpYfk3C6NMKmON48q76hvtHAj0=; b=GT/9hg0Oh9fwH1loPLmTFn1l8seARGX6FTNiDow1nbRRiZ97FClN1IK2u9Ad1mue1W qkfX8Du9spvBRz8t3YkQ3t+cGYs/J2TLzoIL6qBqDCpH4JptVGjt4c9pykLIiJoZLQlR T0+j799H+yIKuytqqAjNdDSpDJKWm1VqZ59wQlYpVb0nncyf872p7+tnwCBLNH7N5Fp+ aIPxt9GjVC3BBi+qNAbMDqDR05ODyzPq9EDWzUsr7fKPCddqWUXxWyXIhlTIOHH/yavk HxYT86YlWYDcrD1jpvhfVMGkG1lv/IcQLO/M1whKt57HKSvc/yqlbmo+i4xqwI4L7Klm eAkA== X-Gm-Message-State: AD7BkJL1/cXja73u6c/7SYv9vbqHVTKlxIusdi1Z5rlAgn0cq9IGyx3xaEzlmj6xKHANqA== X-Received: by 10.194.111.229 with SMTP id il5mr25997548wjb.82.1460376688798; Mon, 11 Apr 2016 05:11:28 -0700 (PDT) Received: from [10.99.1.78] ([80.243.160.112]) by smtp.googlemail.com with ESMTPSA id b1sm27613701wjy.0.2016.04.11.05.11.27 for (version=TLSv1/SSLv3 cipher=OTHER); Mon, 11 Apr 2016 05:11:28 -0700 (PDT) Subject: Re: Context capturing and JSF Parallel-Preloading To: users@deltaspike.apache.org References: <57089C03.5060403@gmail.com> <5708B180.80904@gmail.com> <5708B577.2050805@gmail.com> <5708D26A.4080809@gmail.com> From: Christian Beikov Message-ID: <570B946C.9010708@gmail.com> Date: Mon, 11 Apr 2016 14:11:24 +0200 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.7.2 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/alternative; boundary="------------010302010100090909060009" --------------010302010100090909060009 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Hello, I have finally implemented the context capturing which is probably also interesting for @Futurable. The commit also includes code for deleting specific beans from a context. This is implemented by using AlterableContext.destroy if available and otherwise via OWB/Weld-native mechanisms. Note that there are some bugs in the AlterableContext.destroy implementations which require some hacks to get around. Destroying beans is necessary for testing the session and application scopes. The implementation of the context capturing is not really nice since it requires some reflection hacks but it gets the job done. Would be nice if the CDI spec itself already came with a mechanism to capture contexts ;) I extended the JSF Playground with an example that can be used to test the functionality. Data1 - Data4 tests create beans in the request thread and check if the sub-threads can see the values. Data5 - Data8 tests create beans in the sub-threads and check if the request thread can see the values. You can find the commit here https://github.com/beikov/deltaspike/commit/3a15d6c3b804166a51346981aad12c36cd779b7d I would very much appreciate feedback on the implementation and would like to get that code into deltaspike. Mit freundlichen Grüßen, ------------------------------------------------------------------------ *Christian Beikov* Am 09.04.2016 um 12:34 schrieb Gerhard Petracek: > #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 : > >> 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 : >>> >>> 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 >>>>> : >>>>> 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 getSupplierNames() { /* Some DB call */ } >>>>>>>> >>>>>>>> } >>>>>>>> >>>>>>>> >>>>>>>> ... >>>>>>>> >>>>>>>> #{supplName} >>>>>>>> >>>>>>>> ... >>>>>>>> >>>>>>>> >>>>>>>> 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* >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> --------------010302010100090909060009--