This issue has been created
 
 
JIRA Components / cid:jira-generated-image-avatar-96937009-36d4-498f-b25b-f016b1cc9310 JIRA-104 Open

Every time a Jira REST client is retrieved, 11 new threads are created that keep running

 
View issue   ยท   Add comment
 

Issue created

 
cid:jira-generated-image-avatar-6f744bcb-62cf-41cd-a295-f979d8728fc9 Michael Hamann created this issue on 09/Jan/26 16:37
 
Summary: Every time a Jira REST client is retrieved, 11 new threads are created that keep running
Issue Type: cid:jira-generated-image-avatar-96937009-36d4-498f-b25b-f016b1cc9310 Bug
Affects Versions: 11.1.2
Assignee: Unassigned
Components: API
Created: 09/Jan/26 16:37
Priority: cid:jira-generated-image-static-major-fa2c2012-363c-4d64-8877-14bbff4b0eff Major
Reporter: Michael Hamann
Description:

Steps to reproduce:

Use one of the examples on the https://extensions.xwiki.org/xwiki/bin/view/Extension/JIRA/JIRA%20Module#HExamples and call them several times while taking a thread dump of XWiki's Java process in between.

Expected result:

The number of threads named "httpclient-io:thread-1" and "I/O dispatcher" doesn't grow.

Actual result:

Every time a client is retrieved, one thread named httpclient-io:thread-1 and ten threads named I/O dispatcher followed by a continuously increasing number are created.

In the thread dump, you can see the following stack traces for them:

"httpclient-io:thread-1" #30727
   java.lang.Thread.State: RUNNABLE
        at sun.nio.ch.EPoll.wait(Native Method)
        at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:118)
        at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:129)
        - locked on sun.nio.ch.Util$2@60789986
        - locked on sun.nio.ch.EPollSelectorImpl@6c886242
        at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:141)
        at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor.execute(AbstractMultiworkerIOReactor.java:343)
        at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager.execute(PoolingNHttpClientConnectionManager.java:221)
        at org.apache.http.impl.nio.client.CloseableHttpAsyncClientBase$1.run(CloseableHttpAsyncClientBase.java:64)
        at java.lang.Thread.run(Thread.java:840) 
"I/O dispatcher 470" #30725
   java.lang.Thread.State: RUNNABLE
        at sun.nio.ch.EPoll.wait(Native Method)
        at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:118)
        at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:129)
        - locked on sun.nio.ch.Util$2@56f0d60
        - locked on sun.nio.ch.EPollSelectorImpl@66e4a471
        at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:141)
        at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:255)
        at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)
        at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:591)
        at java.lang.Thread.run(Thread.java:840) 

After some time, this exhausts the number of threads that are available from the operating system and will bring the XWiki instance down.

As a workaround, it is possible to call close() on the returned REST client which terminates the started threads again. In Groovy, a try-with-resource block can be used to automatically close the client. While this could be considered a best practice, it feels too easy to miss and I think it would actually be much better for performance if all clients could share a single connection pool instead of starting a new one for every client.