[jboss-jira] [JBoss JIRA] (WFLY-11489) SFSB not sticky on a single cluster node when clustering of the bean is disabled

Richard Achmatowicz (Jira) issues at jboss.org
Tue Jan 22 04:54:00 EST 2019


    [ https://issues.jboss.org/browse/WFLY-11489?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13685747#comment-13685747 ] 

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)



More information about the jboss-jira mailing list