As far as I understand, thread locals' storage is an implementation detail
in the JVM. There isn't an API to clear all/arbitrary thread locals. Thread
pools, or applications that use thread pools, need to provide hooks to do
that, so that code can do its own cleanup. This is exactly what the
request listener that Carsten mentioned does.

Also, thread pools keep threads for long periods of time (up to the entire
run of the application). There is no guarantee that a thread will be GC'd
ever in the lifetime of an application. That is the point of thread pools
in the first place as threads are relatively expensive to create [1]...at
least expensive until Project Loom [2] is finished.

[1]: https://stackoverflow.com/a/5483105
[2]: https://openjdk.java.net/projects/loom/

-Paul


On Sun, Oct 17, 2021 at 10:53 AM Carsten Ziegeler <cziege...@apache.org>
wrote:

> Hi,
>
> not sure - this heavily depends on how the servlet engine manages the
> threads. I guess usually a thread pool is used, so threads are reused.
> I'm not sure whether thread locals are cleaned up when a thread is
> returned into the pool by every engine and if you can rely on it.
> But using a request listener and cleaning up the thread local works in
> all cases :)
>
> Carsten
>
> Am 17.10.2021 um 13:56 schrieb Roy Teeuwen:
> > Hey Carsten,
> >
> > Could you clarify why you need to clean up the threadlocal when it is
> bound to the thread of a request? Don't the threads of a request get
> garbage collected, and by that way also the ThreadLocal's bound to it
> >
> > Greets,
> > Roy
> >
> >> On 17 Oct 2021, at 09:57, Carsten Ziegeler <cziege...@apache.org>
> wrote:
> >>
> >> Thanks Jörg, initially I got your use case wrong.
> >>
> >> As several people have adviced here now, using an adapter factory
> should give you what you need.
> >>
> >> A more ugly version would be to use a thread local and clean it up when
> the request finishes (via a request listener)
> >>
> >> Another option would be to write a custom resource provider, but that
> might be even more a hack than anything else.
> >>
> >> Regards
> >> Carsten
> >>
> >> Am 16.10.2021 um 16:41 schrieb Jörg Hoh:
> >>> Hi Carsten,
> >>> Am Sa., 16. Okt. 2021 um 09:41 Uhr schrieb Carsten Ziegeler <
> >>> cziege...@apache.org>:
> >>>> I don't think that the RR is the right place for this.
> >>>>
> >>>> If the use case is that during a request the exact same query is
> >>>> executed more than once, then caching the result of the query in Sling
> >>>> is probably not resulting in the wanted gain. I think it is much
> better
> >>>> to avoid executing the query multiple times in the first place -
> >>>>
> >>> That's what I want to achieve. But where should I store the result of
> the
> >>> query so I don't need to execute the query multiple times? As said, I
> don't
> >>> have access to a store, which allows me to store this result within a
> >>> well-defined scope (which is identical to the lifetime of a resource
> >>> resolver). And I don't want to roll such a logic in my own, because
> it's
> >>> definitely not easy to get that right.
> >>>> executing the query is one part but then processing the result is
> >>>> another. And you want to avoid this as well.
> >>>>
> >>> In every invocation of my method a different resource is passed, and I
> need
> >>> to evaluate the result of that query for this resource. To be exact, I
> >>> transform the result of the query into other domain objects, and to
> >>> optimize the performance of this evaluation, I might even store these
> >>> domain objects in a different structure than just a list.
> >>>>
> >>>> In the past 12 years or so we tried various POCs with caching in the
> RR.
> >>>> Always under the (wrong) assumption that Oak/Jackrabbit is the
> >>>> bottleneck. So we added a RR caching all get resources, all list
> >>>> resources, all queries etc. And it turned out that the gain was close
> to
> >>>> zero. Each operation in Oak was pretty fast, but if you execute it
> >>>> hundreds of times during a request, even a fast call becomes the
> >>>> bottleneck. So again, usually the problem is in the upper layers,
> above
> >>>> Sling's resource api.
> >>>>
> >>> I don't want to create a transparent caching layer on a RR level to
> store
> >>> objects which have been requested from the repository. I know that
> this was
> >>> tried in the past, and did not provide the benefits we intended it to
> have.
> >>> I just want to have a simple store (map) on the RR, where I can store
> all
> >>> types of objects, which share the same lifecycle as the resource
> resolver.
> >>> This is handled explicitly, and the developer is responsible to make
> sure,
> >>> that indeed the lifecycles of the resource resolver and the object
> which
> >>> are stored in this temporary storage are compatible. If the developer
> >>> decides to store resources in there, and these resources might change
> over
> >>> the lifetime of this (potentially long-living) resource resolver, so
> be it.
> >>> There should not be any magic, it's just a simple map.
> >>> Jörg
> >>
> >> --
> >> Carsten Ziegeler
> >> Adobe
> >> cziege...@apache.org <mailto:cziege...@apache.org>
> >
>
> --
> Carsten Ziegeler
> Adobe
> cziege...@apache.org
>

Reply via email to