]
Richard Opalka resolved WFLY-12372.
-----------------------------------
Resolution: Done
Performance impact of moving from InjectedValue.getValue() reads to
MSC Supplier impl get() reads
-------------------------------------------------------------------------------------------------
Key: WFLY-12372
URL:
https://issues.jboss.org/browse/WFLY-12372
Project: WildFly
Issue Type: Bug
Components: MSC, Server
Affects Versions: 17.0.1.Final
Reporter: Brian Stansberry
Assignee: Richard Opalka
Priority: Critical
Fix For: 18.0.0.Beta1
A byproduct of the move from the deprecated MSC org.jboss.msc.service.Service API to the
new org.jboss.msc.Service API is that service wiring is shifted from a service getting
refs to dependencies via InjectedValue.getValue() to Supplier.get() calls where the
supplier is obtained from a ServiceBuilder.requires(....) call.
The concurrency characteristics of these two calls are different, which can result in
performance changes if the calls are frequent; i.e. are part of high volume user request
handling call paths. For example:
{code}
org.jboss.msc.service.ServiceRegistrationImpl.getValue()
org.jboss.msc.service.ReadableValueImpl.get()
org.jboss.as.weld.interceptors.Jsr299BindingsInterceptor.processInvocation(InterceptorContext)
org.jboss.as.ee.component.interceptors.UserInterceptorFactory$1.processInvocation(InterceptorContext)
org.jboss.invocation.InterceptorContext.proceed()
{code}
An InjectedValue.getValue() call involves a read of a volatile field, followed by a read
of the getValue() method of the service impl, which is typically also a read of a volatile
field. The stack trace above shows how the Supplier.get() call is handled. The issue is
the ServiceRegistrationImpl.getValue() call includes a synchronization lock on the
ServiceRegistrationImpl value, which means the call is a concurrency chokepoint if
it's used by many requests.
We need to examine the changes we've made related to this MSC API switch and identify
and correct cases where this kind of thing has crept in.