[Geoserver-devel] Turning dispatcher.request into an inheritable thread local

Hi,
I’ve recently found users that have stores using thread locals, either the Dispatcher.REQUEST or
other thread locals set in servlet filters, that are then needed during the data access (yeah, I know,
I know, that breaks proper layering, however these store are applying different behaviors depending
on the service that is used to access them, wms or wfs).

Unfortunately the renderer now is threaded and normally in GS it uses a global thread pool,
meaning that during data access within the renderer one does not get to see the thread locals
anymore. In particular Dispatcher.REQUEST is not accessible anymore.

Solution: disable the global thread pool under request (system variable) so that a new small
thread pool is created from the current thread instead, and make Dispatcher an inheritable
thread local, so that it can be seen from the child threads as well.

Patch attached. Seems innocuous to me, what do you think?

Cheers
Andrea

Ing. Andrea Aime
GeoSolutions S.A.S.
Tech lead

Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy

phone: +39 0584 962313
fax: +39 0584 962313
mob: +39 333 8128928

http://www.geo-solutions.it
http://geo-solutions.blogspot.com/
http://www.youtube.com/user/GeoSolutionsIT
http://www.linkedin.com/in/andreaaime
http://twitter.com/geowolf


(attachments)

threadlocal.patch (3.52 KB)

Seems fine to me. However just to confirm my understanding. When one sets the USE_GLOBAL_RENDERING_POOL to false DefaultWebMapService.getRenderingPool() will return null? And this will cause the renderer to create its own executor which will then inherit from the current thread?

On Thu, Feb 17, 2011 at 11:19 AM, Andrea Aime <andrea.aime@anonymised.com> wrote:

Hi,
I’ve recently found users that have stores using thread locals, either the Dispatcher.REQUEST or
other thread locals set in servlet filters, that are then needed during the data access (yeah, I know,
I know, that breaks proper layering, however these store are applying different behaviors depending
on the service that is used to access them, wms or wfs).

Unfortunately the renderer now is threaded and normally in GS it uses a global thread pool,
meaning that during data access within the renderer one does not get to see the thread locals
anymore. In particular Dispatcher.REQUEST is not accessible anymore.

Solution: disable the global thread pool under request (system variable) so that a new small
thread pool is created from the current thread instead, and make Dispatcher an inheritable
thread local, so that it can be seen from the child threads as well.

Patch attached. Seems innocuous to me, what do you think?

Cheers
Andrea

Ing. Andrea Aime
GeoSolutions S.A.S.
Tech lead

Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy

phone: +39 0584 962313
fax: +39 0584 962313
mob: +39 333 8128928

http://www.geo-solutions.it
http://geo-solutions.blogspot.com/
http://www.youtube.com/user/GeoSolutionsIT
http://www.linkedin.com/in/andreaaime
http://twitter.com/geowolf



The ultimate all-in-one performance toolkit: Intel(R) Parallel Studio XE:
Pinpoint memory and threading errors before they happen.
Find and fix more than 250 security defects in the development cycle.
Locate bottlenecks in serial and parallel code that limit performance.
http://p.sf.net/sfu/intel-dev2devfeb


Geoserver-devel mailing list
Geoserver-devel@anonymised.comsts.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geoserver-devel


Justin Deoliveira
OpenGeo - http://opengeo.org
Enterprise support for open source geospatial.

On Thu, Feb 17, 2011 at 9:50 PM, Justin Deoliveira <jdeolive@anonymised.com.1501…> wrote:

Seems fine to me. However just to confirm my understanding. When one sets the USE_GLOBAL_RENDERING_POOL to false DefaultWebMapService.getRenderingPool() will return null? And this will cause the renderer to create its own executor which will then inherit from the current thread?

That is the idea, yeah. In that case the streaming renderer will create a local thread
pool with
localThreadPool = Executors.newSingleThreadExecutor();

which as far as I understand will create threads which are childs of the current thread.
The global thread pool used otherwise instead is creating threads that are childs of the
thread that started GeoServer. At least this is my basic understanding of it,
not sure it’s really working like that.

For sure the threads in the global pool are not guaranteed to be childs of the current
request threads because… well because they are pooled, kept around and reused

Cheers
Andrea

Ing. Andrea Aime
GeoSolutions S.A.S.
Tech lead

Via Poggio alle Viti 1187
55054 Massarosa (LU)
Italy

phone: +39 0584 962313
fax: +39 0584 962313
mob: +39 333 8128928

http://www.geo-solutions.it
http://geo-solutions.blogspot.com/
http://www.youtube.com/user/GeoSolutionsIT
http://www.linkedin.com/in/andreaaime
http://twitter.com/geowolf