There is 1 update.
 
 
JIRA Components / cid:jira-generated-image-avatar-f6d23264-dc84-4639-9b81-6113d0756d95 JIRA-104 Open

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

 
View issue   ยท   Add comment
 

1 update

 
cid:jira-generated-image-avatar-22c19707-163a-4d39-8287-e93ba40a1f09 Changes by Vincent Massol on 09/Jan/26 17:16
 
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:
{noformat}
"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) {noformat}
{noformat}
"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) {noformat}
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 {{.withCloseable()}} 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.