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