I try to use virtual thread on Apache Tomcat 10.1.16 with this configuration:
<Executor name="tomcatThreadPoolVirtual" class="org.apache.catalina.core.StandardVirtualThreadExecutor"/>
<Connector port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
connectionTimeout="20000"
redirectPort="8443"
maxParameterCount="1000"
useVirtualThreads="true"
/>
But when I make a request, I'm not on a virtual thread : Thread[#76,Thread-14,5,main]
. I profiled my application too but no virtual threads are used.
If I use a Http11NioProtocol instead of Http11Nio2Protocol, all requests are on virtual thread : VirtualThread[#65,http-nio-8080-virt-0]/runnable@ForkJoinPool-1-worker-1
<Executor name="tomcatThreadPoolVirtual" class="org.apache.catalina.core.StandardVirtualThreadExecutor"/>
<!-- A "Connector" represents an endpoint by which requests are received org.apache.coyote.http11.Http11Nio2Protocol
and responses are returned. Documentation at :
HTTP Connector: /docs/config/http.html
AJP Connector: /docs/config/ajp.html
Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
-->
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000"
redirectPort="8443"
maxParameterCount="1000"
useVirtualThreads="true"
/>
Http11Nio2Protocol is not working with virtual threads? Has anyone encountered this problem before?
Yes, your observation is correct. As of Tomcat 10.1.16,
Nio2Endpoint
does not execute your code on a virtual thread, whileNioEndpoint
does. WhileAbstractEndpoint
, a common superclass for both, supports the usage of virtual threads,Nio2Endpoint.setSocketOptions
method callsAbstractEndpoint.processSocket
with parameterdispatch
hardcoded to false, with a comment : Continue processing on the same thread as the acceptor is async. I believe it is associated with a potential asynchronicity of NIO2 Tomcat Connector. Interesting that it does create its Acceptor on a virtual thread, but we cannot benefit much from it.I believe it is a plain bug of this version of Tomcat and it makes sense either to see if it is fixed in its later versions or report it to them.
BTW, it is possible to override Tomcat Connector implementation and the fix seems to be quite easy and the overriding - trivial. Please let me know if you are locked to this version of Tomcat and the virtual nature of your worker threads is important enough and we could try to do it.
Not directly related to your issue, but the line
does not anyhow influence to process of thread creation in our context, instead
AbstractEndpoint.createExecutor
hardcodes the creation oforg.apache.tomcat.util.threads.VirtualThreadExecutor
which is not even aorg.apache.catalina.Executor
, but just ajava.util.concurrent.Executor
.