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