Unless I'm mistaken (which is possible), tapestry will create two distinct 
components when building the component trees, and they will not have access to 
the same variable.

So a template like:
<html ...>
        <t:widget/>
        <t:widget/>
        <t:widget/>
</html>

Would yield three log messages of "rendered 1 time".

--
Robert Hailey



On 2012/11/28 (Nov), at 5:08 PM, Josh Canfield wrote:

> Hi Robert.
> 
> Are you looking for a reason to use PreThreadValue? Or do you just want to
> have a page/component level property that you can access for the life of
> the request?
> 
> In a page or component you just declare the variable and let tapestry do
> it's magic in the background.
> 
>        private int widgetRenderCount = 0;
> 
>        void afterRender() {
>                ++widgetRenderCount;
>                log.debug("{} widgets have now rendered in this request!",
> count);
>        }
> 
> 
> If you want to use it in a singleton service then you need to do the
> plumbing.
> 
> Josh
> 
> 
> On Wed, Nov 28, 2012 at 2:32 PM, Robert Hailey <rhai...@allogy.com> wrote:
> 
>> 
>> I've read the "everyone out of the pool" blog post, but have not been able
>> to find an example of how to best use per-thread value on a page or service
>> (seems like what's provided is an internal tapestry case).
>> 
>> As a (lazy?) tapestry developer, my first thought is to try this:
>> 
>>        @Inject
>>        private PerThreadValue<Integer> widgetRenderCount;
>> 
>> Which probably isn't the expected use-case, because it doesn't work: "no
>> service implements PerThreadValue interface" (or thereabout)
>> 
>> I then though I was probably looking one abstraction layer too deep (as
>> the article does talk about transparent perthread access)... so then I
>> thought of this:
>> 
>>        @Inject
>>        @PerThread
>>        private Integer widgetRenderCount;
>> 
>> Which made a degree of sense because "Persist" is deprecated, but no such
>> annotation exists.
>> 
>> So then I thought I could create my own perthreadvalue-providing service
>> (to realize the first example) like this:
>> 
>>    public void contributeMasterObjectProvider(
>>                OrderedConfiguration<ObjectProvider> configuration,
>>                final PerthreadManager perthreadManager
>>        )
>>    {
>>        configuration.add("PerThreadValue", new ObjectProvider() {
>>            public <T> T provide(Class<T> tClass, AnnotationProvider
>> annotationProvider, ObjectLocator objectLocator) {
>>                return (T)perthreadManager.createValue();
>>            }
>>        });
>>    }
>> 
>> ... but that fails due to the "MasterObjectProvider somehow depends on
>> itself" error message and what's probably a blindingly-obvious lack of
>> knowledge on my part concerning how tapestry actually provides virtually
>> interfaced objects.
>> 
>> So now I have fallen back to patterns like this, that seem to work, but
>> seem to be much clunkier than I would expect:
>> 
>>        @Inject
>>        private PerThreadManager perThreadManager;
>>        private static PerThreadValue<Integer> widgetRenderCount;
>> 
>>        void afterRender() {
>>                if (widgetRenderCount==null) {
>>                        widgetRenderCount=perthreadManager.createValue();
>>                }
>>                int count=widgetRenderCount.get(0);
>>                count++;
>>                log.debug("{} widgets have now rendered in this request!",
>> count);
>>                widgetRenderCount.set(count);
>>        }
>> 
>> 
>> Am I missing something? If so, how is PerThreadValue intended to be used?
>> 
>> --
>> Robert Hailey
>> 
>> 
>> 

Reply via email to