kontent-ai/java-packages

DeliveryClient Hanging, Starving Request Thread Pool

pegelston opened this issue · 2 comments

Hi @aweigold,

There is an intermittent issue with the DeliveryClient which causing a request thread to wait and never return. This seems to happen periodically and causes all request threads to eventually block. When this happens, the server becomes unresponsive (no threads available to service incoming requests).

No clear reproduction path has been identified yet. This seems to occur for us every week or so.

Specifications

  • Version: com.kenticocloud:delivery-sdk-java:1.0.6
  • Platform: Embedded Tomcat w/ Spring Boot

Stacktrace

Below is a thread stacktrace from a waiting thread:

sun.misc.Unsafe.park(Unsafe.java:-2) native
java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) 
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) 
org.apache.http.pool.AbstractConnPool.getPoolEntryBlocking(AbstractConnPool.java:380) 
org.apache.http.pool.AbstractConnPool.access$200(AbstractConnPool.java:69) 
org.apache.http.pool.AbstractConnPool$2.get(AbstractConnPool.java:246) 
org.apache.http.pool.AbstractConnPool$2.get(AbstractConnPool.java:193) 
org.apache.http.impl.conn.PoolingHttpClientConnectionManager.leaseConnection(PoolingHttpClientConnectionManager.java:303) 
org.apache.http.impl.conn.PoolingHttpClientConnectionManager$1.get(PoolingHttpClientConnectionManager.java:279) 
org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:191) 
org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185) 
org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89) 
org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:111) 
org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185) 
org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83) 
org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108) 
org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56) 
com.kenticocloud.delivery.DeliveryClient.lambda$executeRequest$1(DeliveryClient.java:420) 
com.kenticocloud.delivery.DeliveryClient$$Lambda$44/1953333936.execute(:-1) 
com.trustedchoice.kentico.DeliveryClientConfiguration.lambda$trustedChoiceKenticoCache$0(DeliveryClientConfiguration.java:66) 
com.trustedchoice.kentico.DeliveryClientConfiguration$$Lambda$32/826865256.resolveRequest(:-1) 
com.kenticocloud.delivery.DeliveryClient.executeRequest(DeliveryClient.java:419) 
com.kenticocloud.delivery.DeliveryClient.executeRequest(DeliveryClient.java:412) 
com.kenticocloud.delivery.DeliveryClient.getItems(DeliveryClient.java:188) 
com.kenticocloud.delivery.DeliveryClient.getItems(DeliveryClient.java:203) 
com.trustedchoice.sitemap.SiteMapItemRetriever.getSitemapLocation(SiteMapItemRetriever.java:422) 
com.trustedchoice.sitemap.SiteMapItemRetriever.getForRequest(SiteMapItemRetriever.java:105) 
com.trustedchoice.kentico.KenticoContextHolder.loadContextFromRequest(KenticoContextHolder.java:126) 
com.trustedchoice.kentico.KenticoFilter.doFilterInternal(KenticoFilter.java:46) 
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
com.trustedchoice.redirect.RedirectFilter.doFilterInternal(RedirectFilter.java:102) 
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
com.trustedchoice.log.PerformanceLoggingFilter.doFilterInternal(PerformanceLoggingFilter.java:66) 
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
com.trustedchoice.requesthost.RequestHostFilter.doFilterInternal(RequestHostFilter.java:62) 
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317) 
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:158) 
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:100) 
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64) 
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) 
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) 
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214) 
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177) 
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:347) 
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:263) 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) 
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:108) 
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) 
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
org.springframework.session.web.http.SessionRepositoryFilter.doFilterInternal(SessionRepositoryFilter.java:167) 
org.springframework.session.web.http.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:80) 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) 
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:106) 
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) 
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) 
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) 
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) 
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504) 
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) 
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) 
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) 
org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:677) 
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) 
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) 
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) 
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790) 
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459) 
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) 
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) 
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) 
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
java.lang.Thread.run(Thread.java:748) 

Thanks for writing this up @pegelston , and good find!

Fixed in 2.0.1