[
https://issues.jboss.org/browse/WFLY-11489?page=com.atlassian.jira.plugin...
]
Richard Achmatowicz edited comment on WFLY-11489 at 1/22/19 4:53 AM:
---------------------------------------------------------------------
I now have a fix for this issue, in the sense that it fixes the reproducer problem and
also passes the testsuite, but i'm going to have to try to write some more test cases
before pushing it out. The changes affect both the EJB client and Wildfly codebases.
The main changes are as follows:
1. Correct affinity assignment on server during session creation
2. Adjust affinity assignment on server during invocation
3. Adjust affinity processing in NamingInterceptor
4. Add in more debug/trace logging so we can see what is going on with affinity
processing
1. This required using the values Cache.getStrongAffinity() and Cache.getWeakAffinity() to
assign affinity values to new sessions. In the case where strong affinity evaluates to
NodeAffinity (as with beans which have passivationEnabled=false), don't send back any
affinity. This will cause the client to convert (NONE, NONE) to (targetAffinity, NONE)
which works.
2. Generally, the only time the server should adjust affinity on invocations is when the
weak affinity needs to be adjusted for an invocation which has failed over. Use the
Cache.getWeakAffinity() for that. Also, in order to make the testsuite pass, I had to
leave in a bit of code which forces SLSB to have strong affinity to "the
cluster"; in other words, when a SLSB is sent to a clustered node, its strong
affinity is always forced to "the cluster". I'll have to double check how
this worked in the past; in general, it seems wrong (a SLSB with affinity (NONE,NONE)
should not be converted to (Cluster, NONE) just because it was non-deterministically sent
to a clustered node).
3. If the user has defined a PROVDER_URL in the JNDI naming context, in the case of a
bean with default affinity (NONE, NONE), the NamingInterceptor will choose one URI in the
PROVIDER_URL as the target; it can do this because (NONE, NONE) does not place any
restrictions on the choice of target. This also has the consequence of bypassing the
DiscoveryEJBClientInterceptor. However, the NamingInterceptor was calling
DiscoveryEJBClientInterceptor.setupAffinities() before the invocation went out, which
means that the server adjustments were not being correctly updated during reply
processing. I Changed this to update the affinities on the way back, and it works as
expected now.
Generally, such target selection does not check that the module is even deployed on that
target before sending the invocation as discovery is bypassed; but that is for another
day.
4. I have added in logging at every location where affinities are updates. This makes it a
lot easier to follow what is going on.
I'll tidy up the current PR and post a ink to it.
was (Author: rachmato):
I now have a fix for this issue, in the sense that it fixes the reproducer problem and
also passes the testsuite, but i'm going to have to try to write some more test cases
before pushing it out. The changes affect both the EJB client and Wildfly codebases.
The main changes are as follows:
1. Correct affinity assignment on server during session creation
2. Adjust affinity assignment on server during invocation
3. Adjust affinity processing in NamingInterceptor
4. Add in more debug/trace logging so we can see what is going on with affinity
processing
1. This required using the values Cache.getStrongAffinity() and Cache.getWeakAffinity() to
assign affinity values to new sessions. In the case where strong affinity evaluates to
NodeAffinity (as with beans which have passivationEnabled=false), don't send back any
affinity. This will cause the client to convert (NONE, NONE) to (targetAffinity, NONE)
which works.
2. Generally, the only time the server should adjust affinity on invocations is when the
weak affinity needs to be adjusted for an invocation which has failed over. Use the
Cache.getWeakAffinity() for that. Also, in order to make the testsuite pass, I had to
leave in a bit of code which forces SLSB to have strong affinity to "the
cluster"; in other words, when a SLSB is sent to a clustered node, its strong
affinity is always forced to "the cluster". I'll have to double check how
this worked in the past; in general, it seems wrong (a SLSB with affinity (NONE,NONE)
should not be converted to (Cluster, NONE) just because it was non-deterministically sent
to a clustered node).
3. If the user has defined a PROVDER_URL in the JNDI naming context, in the case of a
bean with default affinity (NONE, NONE), the NamingInterceptor will choose one URI in the
PROVIDER_URL as the target; it can do this because (NONE, NONE) does not place any
restrictions on the choice of target. However, the NamingInterceptor was calling
DiscoveryEJBClientInterceptor.setupAffinities() before the invocation went out, which
means that the server adjustments were not being correctly updated during reply
processing. I Changed this to update the affinities on the way back, and it works as
expected now.
4. I have added in logging at every location where affinities are updates. This makes it a
lot easier to follow what is going on.
I'll tidy up the current PR and post a ink to it.
SFSB not sticky on a single cluster node when clustering of the bean
is disabled
--------------------------------------------------------------------------------
Key: WFLY-11489
URL:
https://issues.jboss.org/browse/WFLY-11489
Project: WildFly
Issue Type: Bug
Components: Clustering, Remoting
Affects Versions: 15.0.0.Final
Environment: A clustered environment with 2 nodes. Both nodes started with an
unmodified {{standalone-ha.xml}} configuration (see _Steps to Reproduce_)
This issue happens on 15.0.0.Final and was tested as well as on current head (sha:
372697282dccefd0b9df48e6aa4dcb69e1c4b40f).
Reporter: Jörg Bäsner
Assignee: Richard Achmatowicz
Priority: Major
Attachments: reproducer.zip
In case a stateful session bean is annotated with:
{{@Stateful(passivationCapable=false)}}
then the serialization is *disabled* and thus the bean is only available on a single
cluster node.
When a client now calls two different methods on this stateful bean it intermittently
ends up on different cluster nodes, resulting in the following Exception:
{code}
ERROR [org.jboss.as.ejb3.invocation] (default task-2) WFLYEJB0034: EJB Invocation failed
on component TestSessionEJB for method public abstract void
test.ITestSession.method2(java.lang.String,java.lang.String) throws
javax.ejb.EJBException,java.rmi.RemoteException: javax.ejb.NoSuchEJBException:
WFLYEJB0168: Could not find EJB with id UUIDSessionID
[4b0f4a27-40ba-411b-8852-0108a5ec64f4]
at
org.jboss.as.ejb3.component.stateful.StatefulComponentInstanceInterceptor.processInvocation(StatefulComponentInstanceInterceptor.java:55)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
at
org.jboss.as.ejb3.component.interceptors.AdditionalSetupInterceptor.processInvocation(AdditionalSetupInterceptor.java:54)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
at
org.jboss.invocation.InterceptorContext$Invocation.proceed(InterceptorContext.java:509)
at
org.jboss.weld.module.ejb.AbstractEJBRequestScopeActivationInterceptor.aroundInvoke(AbstractEJBRequestScopeActivationInterceptor.java:81)
at
org.jboss.as.weld.ejb.EjbRequestScopeActivationInterceptor.processInvocation(EjbRequestScopeActivationInterceptor.java:89)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
at
org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
at
org.jboss.as.ejb3.component.invocationmetrics.WaitTimeInterceptor.processInvocation(WaitTimeInterceptor.java:47)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
at
org.jboss.as.ejb3.security.SecurityContextInterceptor.processInvocation(SecurityContextInterceptor.java:100)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
at
org.jboss.as.ejb3.deployment.processors.StartupAwaitInterceptor.processInvocation(StartupAwaitInterceptor.java:22)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
at
org.jboss.as.ejb3.component.interceptors.ShutDownInterceptorFactory$1.processInvocation(ShutDownInterceptorFactory.java:64)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
at
org.jboss.as.ejb3.deployment.processors.EjbSuspendInterceptor.processInvocation(EjbSuspendInterceptor.java:57)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
at
org.jboss.as.ejb3.component.interceptors.LoggingInterceptor.processInvocation(LoggingInterceptor.java:67)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
at
org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
at
org.jboss.invocation.ContextClassLoaderInterceptor.processInvocation(ContextClassLoaderInterceptor.java:60)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
at org.jboss.invocation.InterceptorContext.run(InterceptorContext.java:438)
at
org.wildfly.security.manager.WildFlySecurityManager.doChecked(WildFlySecurityManager.java:618)
at
org.jboss.invocation.AccessCheckingInterceptor.processInvocation(AccessCheckingInterceptor.java:57)
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)
at
org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:53)
at org.jboss.as.ee.component.ViewService$View.invoke(ViewService.java:198)
at
org.wildfly.security.auth.server.SecurityIdentity.runAsFunctionEx(SecurityIdentity.java:406)
at
org.jboss.as.ejb3.remote.AssociationImpl.invokeWithIdentity(AssociationImpl.java:565)
at org.jboss.as.ejb3.remote.AssociationImpl.invokeMethod(AssociationImpl.java:546)
at
org.jboss.as.ejb3.remote.AssociationImpl.lambda$receiveInvocationRequest$0(AssociationImpl.java:197)
at
org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1985)
at
org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1487)
at
org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1349)
at java.lang.Thread.run(Thread.java:748)
{code}
--
This message was sent by Atlassian Jira
(v7.12.1#712002)