Ah right, I was assuming a loop, which would be one instance.

Hmm... I can't remember a time when I've needed to talk across component
instances where using a @SessionState object didn't work. But I can see how
you might want to not have the state persist between requests...

If someone doesn't come up with a better idea, you could copy the
ApplicationStateWorker and create a @PerThread annotation and
PerThreadWorker

http://tapestry.apache.org/tapestry5/apidocs/src-html/org/apache/tapestry5/internal/transform/ApplicationStateWorker.html

Josh

On Wed, Nov 28, 2012 at 3:22 PM, Robert Hailey <rhai...@allogy.com> wrote:

>
> 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