KEYCLOAK-3202 Creating users causes memory leak
This commit is contained in:
parent
7e0238d1c7
commit
3fc215d041
10 changed files with 51 additions and 23 deletions
|
@ -90,9 +90,6 @@
|
||||||
<local-cache name="offlineSessions"/>
|
<local-cache name="offlineSessions"/>
|
||||||
<local-cache name="loginFailures"/>
|
<local-cache name="loginFailures"/>
|
||||||
<local-cache name="work"/>
|
<local-cache name="work"/>
|
||||||
<local-cache name="realmVersions">
|
|
||||||
<transaction mode="BATCH" locking="PESSIMISTIC"/>
|
|
||||||
</local-cache>
|
|
||||||
</cache-container>
|
</cache-container>
|
||||||
<xsl:apply-templates select="node()|@*"/>
|
<xsl:apply-templates select="node()|@*"/>
|
||||||
</xsl:copy>
|
</xsl:copy>
|
||||||
|
|
|
@ -8,7 +8,5 @@ embed-server --server-config=standalone-ha.xml
|
||||||
/subsystem=infinispan/cache-container=keycloak/distributed-cache=offlineSessions:add(mode="SYNC",owners="1")
|
/subsystem=infinispan/cache-container=keycloak/distributed-cache=offlineSessions:add(mode="SYNC",owners="1")
|
||||||
/subsystem=infinispan/cache-container=keycloak/distributed-cache=loginFailures:add(mode="SYNC",owners="1")
|
/subsystem=infinispan/cache-container=keycloak/distributed-cache=loginFailures:add(mode="SYNC",owners="1")
|
||||||
/subsystem=infinispan/cache-container=keycloak/replicated-cache=work:add(mode="SYNC")
|
/subsystem=infinispan/cache-container=keycloak/replicated-cache=work:add(mode="SYNC")
|
||||||
/subsystem=infinispan/cache-container=keycloak/local-cache=realmVersions:add()
|
|
||||||
/subsystem=infinispan/cache-container=keycloak/local-cache=realmVersions/transaction=TRANSACTION:add(mode=BATCH,locking=PESSIMISTIC)
|
|
||||||
/extension=org.keycloak.keycloak-server-subsystem/:add(module=org.keycloak.keycloak-server-subsystem)
|
/extension=org.keycloak.keycloak-server-subsystem/:add(module=org.keycloak.keycloak-server-subsystem)
|
||||||
/subsystem=keycloak-server:add(web-context=auth)
|
/subsystem=keycloak-server:add(web-context=auth)
|
|
@ -21,6 +21,7 @@ import org.infinispan.configuration.cache.CacheMode;
|
||||||
import org.infinispan.configuration.cache.Configuration;
|
import org.infinispan.configuration.cache.Configuration;
|
||||||
import org.infinispan.configuration.cache.ConfigurationBuilder;
|
import org.infinispan.configuration.cache.ConfigurationBuilder;
|
||||||
import org.infinispan.configuration.global.GlobalConfigurationBuilder;
|
import org.infinispan.configuration.global.GlobalConfigurationBuilder;
|
||||||
|
import org.infinispan.eviction.EvictionStrategy;
|
||||||
import org.infinispan.eviction.EvictionType;
|
import org.infinispan.eviction.EvictionType;
|
||||||
import org.infinispan.manager.DefaultCacheManager;
|
import org.infinispan.manager.DefaultCacheManager;
|
||||||
import org.infinispan.manager.EmbeddedCacheManager;
|
import org.infinispan.manager.EmbeddedCacheManager;
|
||||||
|
@ -97,6 +98,17 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
|
||||||
cacheManager = (EmbeddedCacheManager) new InitialContext().lookup(cacheContainerLookup);
|
cacheManager = (EmbeddedCacheManager) new InitialContext().lookup(cacheContainerLookup);
|
||||||
containerManaged = true;
|
containerManaged = true;
|
||||||
|
|
||||||
|
cacheManager.defineConfiguration(InfinispanConnectionProvider.REALM_REVISIONS_CACHE_NAME, getRevisionCacheConfig(true, InfinispanConnectionProvider.REALM_REVISIONS_CACHE_DEFAULT_MAX));
|
||||||
|
cacheManager.getCache(InfinispanConnectionProvider.REALM_CACHE_NAME, true);
|
||||||
|
|
||||||
|
long maxEntries = cacheManager.getCache(InfinispanConnectionProvider.USER_CACHE_NAME).getCacheConfiguration().eviction().maxEntries();
|
||||||
|
if (maxEntries <= 0) {
|
||||||
|
maxEntries = InfinispanConnectionProvider.USER_REVISIONS_CACHE_DEFAULT_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
cacheManager.defineConfiguration(InfinispanConnectionProvider.USER_REVISIONS_CACHE_NAME, getRevisionCacheConfig(true, maxEntries));
|
||||||
|
cacheManager.getCache(InfinispanConnectionProvider.USER_REVISIONS_CACHE_NAME, true);
|
||||||
|
|
||||||
logger.debugv("Using container managed Infinispan cache container, lookup={1}", cacheContainerLookup);
|
logger.debugv("Using container managed Infinispan cache container, lookup={1}", cacheContainerLookup);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Failed to retrieve cache container", e);
|
throw new RuntimeException("Failed to retrieve cache container", e);
|
||||||
|
@ -162,12 +174,32 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
|
||||||
.transaction().transactionMode(TransactionMode.TRANSACTIONAL);
|
.transaction().transactionMode(TransactionMode.TRANSACTIONAL);
|
||||||
counterConfigBuilder.transaction().transactionManagerLookup(new DummyTransactionManagerLookup());
|
counterConfigBuilder.transaction().transactionManagerLookup(new DummyTransactionManagerLookup());
|
||||||
counterConfigBuilder.transaction().lockingMode(LockingMode.PESSIMISTIC);
|
counterConfigBuilder.transaction().lockingMode(LockingMode.PESSIMISTIC);
|
||||||
Configuration counterCacheConfiguration = counterConfigBuilder.build();
|
|
||||||
|
|
||||||
cacheManager.defineConfiguration(InfinispanConnectionProvider.VERSION_CACHE_NAME, counterCacheConfiguration);
|
cacheManager.defineConfiguration(InfinispanConnectionProvider.REALM_REVISIONS_CACHE_NAME, getRevisionCacheConfig(false, InfinispanConnectionProvider.REALM_REVISIONS_CACHE_DEFAULT_MAX));
|
||||||
|
cacheManager.getCache(InfinispanConnectionProvider.REALM_CACHE_NAME, true);
|
||||||
|
|
||||||
cacheManager.defineConfiguration(InfinispanConnectionProvider.AUTHORIZATION_CACHE_NAME,
|
cacheManager.defineConfiguration(InfinispanConnectionProvider.AUTHORIZATION_CACHE_NAME,
|
||||||
new ConfigurationBuilder().eviction().type(EvictionType.COUNT).size(100).simpleCache(true).build());
|
new ConfigurationBuilder().eviction().type(EvictionType.COUNT).size(100).simpleCache(true).build());
|
||||||
|
|
||||||
|
long maxEntries = cacheManager.getCache(InfinispanConnectionProvider.USER_CACHE_NAME).getCacheConfiguration().eviction().maxEntries();
|
||||||
|
if (maxEntries <= 0) {
|
||||||
|
maxEntries = InfinispanConnectionProvider.USER_REVISIONS_CACHE_DEFAULT_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
cacheManager.defineConfiguration(InfinispanConnectionProvider.USER_REVISIONS_CACHE_NAME, getRevisionCacheConfig(false, maxEntries));
|
||||||
|
cacheManager.getCache(InfinispanConnectionProvider.USER_REVISIONS_CACHE_NAME, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Configuration getRevisionCacheConfig(boolean managed, long maxEntries) {
|
||||||
|
ConfigurationBuilder cb = new ConfigurationBuilder();
|
||||||
|
cb.invocationBatching().enable().transaction().transactionMode(TransactionMode.TRANSACTIONAL);
|
||||||
|
if (!managed) {
|
||||||
|
cb.transaction().transactionManagerLookup(new DummyTransactionManagerLookup());
|
||||||
|
}
|
||||||
|
cb.transaction().lockingMode(LockingMode.PESSIMISTIC);
|
||||||
|
|
||||||
|
cb.eviction().strategy(EvictionStrategy.LRU).type(EvictionType.COUNT).size(maxEntries);
|
||||||
|
return cb.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,15 +25,21 @@ import org.keycloak.provider.Provider;
|
||||||
*/
|
*/
|
||||||
public interface InfinispanConnectionProvider extends Provider {
|
public interface InfinispanConnectionProvider extends Provider {
|
||||||
|
|
||||||
public static final String VERSION_CACHE_NAME = "realmVersions";
|
String REALM_CACHE_NAME = "realms";
|
||||||
static final String REALM_CACHE_NAME = "realms";
|
String REALM_REVISIONS_CACHE_NAME = "realmRevisions";
|
||||||
static final String USER_CACHE_NAME = "users";
|
int REALM_REVISIONS_CACHE_DEFAULT_MAX = 10000;
|
||||||
static final String SESSION_CACHE_NAME = "sessions";
|
|
||||||
static final String OFFLINE_SESSION_CACHE_NAME = "offlineSessions";
|
String USER_CACHE_NAME = "users";
|
||||||
static final String LOGIN_FAILURE_CACHE_NAME = "loginFailures";
|
String USER_REVISIONS_CACHE_NAME = "userRevisions";
|
||||||
static final String WORK_CACHE_NAME = "work";
|
int USER_REVISIONS_CACHE_DEFAULT_MAX = 100000;
|
||||||
|
|
||||||
|
String SESSION_CACHE_NAME = "sessions";
|
||||||
|
String OFFLINE_SESSION_CACHE_NAME = "offlineSessions";
|
||||||
|
String LOGIN_FAILURE_CACHE_NAME = "loginFailures";
|
||||||
|
String WORK_CACHE_NAME = "work";
|
||||||
String AUTHORIZATION_CACHE_NAME = "authorization";
|
String AUTHORIZATION_CACHE_NAME = "authorization";
|
||||||
|
|
||||||
|
|
||||||
<K, V> Cache<K, V> getCache(String name);
|
<K, V> Cache<K, V> getCache(String name);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,6 +139,7 @@ public abstract class CacheManager {
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
cache.clear();
|
cache.clear();
|
||||||
|
revisions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addInvalidations(Predicate<Map.Entry<String, Revisioned>> predicate, Set<String> invalidations) {
|
public void addInvalidations(Predicate<Map.Entry<String, Revisioned>> predicate, Set<String> invalidations) {
|
||||||
|
|
|
@ -48,7 +48,7 @@ public class InfinispanCacheRealmProviderFactory implements CacheRealmProviderFa
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (realmCache == null) {
|
if (realmCache == null) {
|
||||||
Cache<String, Revisioned> cache = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.REALM_CACHE_NAME);
|
Cache<String, Revisioned> cache = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.REALM_CACHE_NAME);
|
||||||
Cache<String, Long> revisions = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.VERSION_CACHE_NAME);
|
Cache<String, Long> revisions = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.REALM_REVISIONS_CACHE_NAME);
|
||||||
realmCache = new RealmCacheManager(cache, revisions);
|
realmCache = new RealmCacheManager(cache, revisions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ public class InfinispanCacheUserProviderFactory implements CacheUserProviderFact
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (userCache == null) {
|
if (userCache == null) {
|
||||||
Cache<String, Revisioned> cache = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.USER_CACHE_NAME);
|
Cache<String, Revisioned> cache = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.USER_CACHE_NAME);
|
||||||
Cache<String, Long> revisions = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.VERSION_CACHE_NAME);
|
Cache<String, Long> revisions = session.getProvider(InfinispanConnectionProvider.class).getCache(InfinispanConnectionProvider.USER_REVISIONS_CACHE_NAME);
|
||||||
userCache = new UserCacheManager(cache, revisions);
|
userCache = new UserCacheManager(cache, revisions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ public class UserCacheManager extends CacheManager {
|
||||||
@Override
|
@Override
|
||||||
public void clear() {
|
public void clear() {
|
||||||
cache.clear();
|
cache.clear();
|
||||||
|
revisions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -63,7 +63,6 @@ public class KeycloakServerDeploymentProcessor implements DeploymentUnitProcesso
|
||||||
st.addDependency(cacheContainerService.append("offlineSessions"));
|
st.addDependency(cacheContainerService.append("offlineSessions"));
|
||||||
st.addDependency(cacheContainerService.append("loginFailures"));
|
st.addDependency(cacheContainerService.append("loginFailures"));
|
||||||
st.addDependency(cacheContainerService.append("work"));
|
st.addDependency(cacheContainerService.append("work"));
|
||||||
st.addDependency(cacheContainerService.append("realmVersions"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,9 +33,6 @@
|
||||||
<local-cache name="offlineSessions"/>
|
<local-cache name="offlineSessions"/>
|
||||||
<local-cache name="loginFailures"/>
|
<local-cache name="loginFailures"/>
|
||||||
<local-cache name="work"/>
|
<local-cache name="work"/>
|
||||||
<local-cache name="realmVersions">
|
|
||||||
<transaction mode="BATCH" locking="PESSIMISTIC"/>
|
|
||||||
</local-cache>
|
|
||||||
<local-cache name="authorization">
|
<local-cache name="authorization">
|
||||||
<eviction max-entries="100" strategy="LRU"/>
|
<eviction max-entries="100" strategy="LRU"/>
|
||||||
</local-cache>
|
</local-cache>
|
||||||
|
@ -99,9 +96,6 @@
|
||||||
<distributed-cache name="offlineSessions" mode="SYNC" owners="1"/>
|
<distributed-cache name="offlineSessions" mode="SYNC" owners="1"/>
|
||||||
<distributed-cache name="loginFailures" mode="SYNC" owners="1"/>
|
<distributed-cache name="loginFailures" mode="SYNC" owners="1"/>
|
||||||
<replicated-cache name="work" mode="SYNC" />
|
<replicated-cache name="work" mode="SYNC" />
|
||||||
<local-cache name="realmVersions">
|
|
||||||
<transaction mode="BATCH" locking="PESSIMISTIC"/>
|
|
||||||
</local-cache>
|
|
||||||
</cache-container>
|
</cache-container>
|
||||||
<cache-container name="server" aliases="singleton cluster" default-cache="default" module="org.wildfly.clustering.server">
|
<cache-container name="server" aliases="singleton cluster" default-cache="default" module="org.wildfly.clustering.server">
|
||||||
<transport lock-timeout="60000"/>
|
<transport lock-timeout="60000"/>
|
||||||
|
|
Loading…
Reference in a new issue