Unnecessary getRootPath() file system access on every request adds overhead

Description

Now that I've added Lucee to the Techempower language benchmarks, I'm performance tuning the tests-- some of which just hit a hello world page with 512 threads to see how many requests the server can process a second.

One of the very first things I saw when profiling the JVM, was basically 512 threads all running the exact same code in the stack trace below.

Every page request to Lucee calls

ReqRspUtil.getRootPath(srvContext);

as part of CFMLEngineImpl.getCFMLFactory() which results in a touch to the file system. This is not a check which needs to be run more than once per server restart since the servlet context root will not change. Lucee needs to cache this lookup and not invoke the file system hit every request.

FWIW, "inspect templates" was set to "never" during this test.

java.lang.Thread.State: RUNNABLE at sun.nio.fs.UnixNativeDispatcher.lstat0(Native Method) at sun.nio.fs.UnixNativeDispatcher.lstat(UnixNativeDispatcher.java:305) at sun.nio.fs.UnixFileAttributes.get(UnixFileAttributes.java:72) at sun.nio.fs.UnixPath.toRealPath(UnixPath.java:874) at runwar.undertow.MappedResourceManager.getResource(MappedResourceManager.java:126) at io.undertow.servlet.spec.ServletContextImpl.getRealPath(ServletContextImpl.java:385) at lucee.runtime.net.http.ReqRspUtil.getRootPath(ReqRspUtil.java:526) at lucee.runtime.engine.CFMLEngineImpl.getCFMLFactory(CFMLEngineImpl.java:1087) at lucee.runtime.engine.CFMLEngineImpl._service(CFMLEngineImpl.java:1129) at lucee.runtime.engine.CFMLEngineImpl.serviceCFML(CFMLEngineImpl.java:1120) at lucee.loader.engine.CFMLEngineWrapper.serviceCFML(CFMLEngineWrapper.java:97) at lucee.loader.servlet.CFMLServlet.service(CFMLServlet.java:51) at javax.servlet.http.HttpServlet.service(HttpServlet.java:590) at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)

Environment

None

Activity

Show:

Tim Smolders 19 April 2021 at 09:56

Could this have caused this error repeatedly showing up in stdout.log leading up to 500/server unresponsive?

  • [ERROR] io.undertow.request: UT005023: Exception handling request to /applicatie/index.cfm

  • javax.servlet.ServletException: cannot determinate webcontext root, the ServletContext from class [io.undertow.servlet.spec.ServletContextImpl] is returning null for the method call sc.getRealPath("/"), possibly due to configuration problem.

Brad Wood 13 April 2021 at 16:53
Edited

That probably depends on whether the servlet's resource manager follows symlinks or not. If ServetContext.getRealPath() returns the location of the symlink, then it should still point to wherever the symlink points. You can probably test that by checking what you get from this:

getPageContext().getServletContext().getRealPath( '/' )

See if you get your symlink back or if you get the folder that the symlink points to back.

Tom Chiverton 13 April 2021 at 14:36

“This is not a check which needs to be run more than once per server restart since the servlet context root will not change”

What about if the target is a symlink ?

Brad Wood 22 February 2021 at 19:37

Thanks for the information!

Fixed

Details

Assignee

Michael Offner

Reporter

Priority

Fix versions

New Issue warning screen

Before you create a new Issue, please post to the mailing list first https://dev.lucee.org

Once the issue has been verified, one of the Lucee team will ask you to file an issue

Created 19 February 2021 at 01:59
Updated 19 April 2021 at 09:56
Resolved 12 April 2021 at 10:12

Flag notifications