On Wednesday, November 28, 2012, Robert Hailey 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 always. Some of the best examples are in the Tapestry source code.


> As a (lazy?) tapestry developer, my first thought is to try this:
>
>         @Inject
>         private PerThreadValue<Integer> widgetRenderCount;
>
>
Although Tapestry could be extended to support this pattern, it is not so
out of the box.


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


The path of least resistance is to define your own service for tracking
this kind of per-request information. You can then inject this service into
any page or component that wants it.

The scope annotation can be used to configure that service as per-thread

http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/annotations/Scope.html
http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/ioc/ScopeConstants.html




>
> --
> Robert Hailey
>
>
>

-- 
Howard M. Lewis Ship

Creator of Apache Tapestry

The source for Tapestry training, mentoring and support. Contact me to
learn how I can get you up and productive in Tapestry fast!

(971) 678-5210
http://howardlewisship.com

Reply via email to