Set idle time the same as for the internal cache, but extend it for refreshes
Closes #32100 Signed-off-by: Alexander Schwartz <aschwart@redhat.com> Signed-off-by: Michal Hajas <mhajas@redhat.com> Co-authored-by: Michal Hajas <mhajas@redhat.com>
This commit is contained in:
parent
03e0fb0601
commit
d9dfe74e8b
3 changed files with 24 additions and 54 deletions
|
@ -135,11 +135,10 @@ public class InfinispanUserLoginFailureProviderFactory implements UserLoginFailu
|
|||
InfinispanConnectionProvider ispn = session.getProvider(InfinispanConnectionProvider.class);
|
||||
|
||||
Cache<LoginFailureKey, SessionEntityWrapper<LoginFailureEntity>> loginFailuresCache = ispn.getCache(InfinispanConnectionProvider.LOGIN_FAILURE_CACHE_NAME);
|
||||
checkRemoteCache(session, loginFailuresCache, (RealmModel realm) ->
|
||||
Time.toMillis(realm.getMaxDeltaTimeSeconds()), SessionTimeouts::getLoginFailuresLifespanMs, SessionTimeouts::getLoginFailuresMaxIdleMs);
|
||||
checkRemoteCache(session, loginFailuresCache, SessionTimeouts::getLoginFailuresLifespanMs, SessionTimeouts::getLoginFailuresMaxIdleMs);
|
||||
}
|
||||
|
||||
private <K, V extends SessionEntity> RemoteCache checkRemoteCache(KeycloakSession session, Cache<K, SessionEntityWrapper<V>> ispnCache, RemoteCacheInvoker.MaxIdleTimeLoader maxIdleLoader,
|
||||
private <K, V extends SessionEntity> RemoteCache checkRemoteCache(KeycloakSession session, Cache<K, SessionEntityWrapper<V>> ispnCache,
|
||||
SessionFunction<V> lifespanMsLoader, SessionFunction<V> maxIdleTimeMsLoader) {
|
||||
Set<RemoteStore> remoteStores = InfinispanUtil.getRemoteStores(ispnCache);
|
||||
|
||||
|
@ -155,7 +154,7 @@ public class InfinispanUserLoginFailureProviderFactory implements UserLoginFailu
|
|||
throw new IllegalStateException("No remote cache available for the infinispan cache: " + ispnCache.getName());
|
||||
}
|
||||
|
||||
remoteCacheInvoker.addRemoteCache(ispnCache.getName(), remoteCache, maxIdleLoader);
|
||||
remoteCacheInvoker.addRemoteCache(ispnCache.getName(), remoteCache);
|
||||
|
||||
RemoteCacheSessionListener hotrodListener = RemoteCacheSessionListener.createListener(session, ispnCache, remoteCache, lifespanMsLoader, maxIdleTimeMsLoader, null);
|
||||
remoteCache.addClientListener(hotrodListener);
|
||||
|
|
|
@ -317,37 +317,27 @@ public class InfinispanUserSessionProviderFactory implements UserSessionProvider
|
|||
InfinispanConnectionProvider ispn = session.getProvider(InfinispanConnectionProvider.class);
|
||||
|
||||
Cache<String, SessionEntityWrapper<UserSessionEntity>> sessionsCache = ispn.getCache(InfinispanConnectionProvider.USER_SESSION_CACHE_NAME);
|
||||
RemoteCache sessionsRemoteCache = checkRemoteCache(session, sessionsCache, (RealmModel realm) -> {
|
||||
// We won't write to the remoteCache during token refresh, so the timeout needs to be longer.
|
||||
return Time.toMillis(realm.getSsoSessionMaxLifespan());
|
||||
}, SessionTimeouts::getUserSessionLifespanMs, SessionTimeouts::getUserSessionMaxIdleMs);
|
||||
RemoteCache sessionsRemoteCache = checkRemoteCache(session, sessionsCache, SessionTimeouts::getUserSessionLifespanMs, SessionTimeouts::getUserSessionMaxIdleMs);
|
||||
|
||||
if (sessionsRemoteCache != null) {
|
||||
lastSessionRefreshStore = new CrossDCLastSessionRefreshStoreFactory().createAndInit(session, sessionsCache, false);
|
||||
}
|
||||
|
||||
Cache<UUID, SessionEntityWrapper<AuthenticatedClientSessionEntity>> clientSessionsCache = ispn.getCache(InfinispanConnectionProvider.CLIENT_SESSION_CACHE_NAME);
|
||||
checkRemoteCache(session, clientSessionsCache, (RealmModel realm) -> {
|
||||
// We won't write to the remoteCache during token refresh, so the timeout needs to be longer.
|
||||
return Time.toMillis(realm.getSsoSessionMaxLifespan());
|
||||
}, SessionTimeouts::getClientSessionLifespanMs, SessionTimeouts::getClientSessionMaxIdleMs);
|
||||
checkRemoteCache(session, clientSessionsCache, SessionTimeouts::getClientSessionLifespanMs, SessionTimeouts::getClientSessionMaxIdleMs);
|
||||
|
||||
Cache<String, SessionEntityWrapper<UserSessionEntity>> offlineSessionsCache = ispn.getCache(InfinispanConnectionProvider.OFFLINE_USER_SESSION_CACHE_NAME);
|
||||
RemoteCache offlineSessionsRemoteCache = checkRemoteCache(session, offlineSessionsCache, (RealmModel realm) -> {
|
||||
return Time.toMillis(realm.getOfflineSessionIdleTimeout());
|
||||
}, this::deriveOfflineSessionCacheEntryLifespanMs, SessionTimeouts::getOfflineSessionMaxIdleMs);
|
||||
RemoteCache offlineSessionsRemoteCache = checkRemoteCache(session, offlineSessionsCache, this::deriveOfflineSessionCacheEntryLifespanMs, SessionTimeouts::getOfflineSessionMaxIdleMs);
|
||||
|
||||
if (offlineSessionsRemoteCache != null) {
|
||||
offlineLastSessionRefreshStore = new CrossDCLastSessionRefreshStoreFactory().createAndInit(session, offlineSessionsCache, true);
|
||||
}
|
||||
|
||||
Cache<UUID, SessionEntityWrapper<AuthenticatedClientSessionEntity>> offlineClientSessionsCache = ispn.getCache(InfinispanConnectionProvider.OFFLINE_CLIENT_SESSION_CACHE_NAME);
|
||||
checkRemoteCache(session, offlineClientSessionsCache, (RealmModel realm) -> {
|
||||
return Time.toMillis(realm.getOfflineSessionIdleTimeout());
|
||||
}, this::deriveOfflineClientSessionCacheEntryLifespanOverrideMs, SessionTimeouts::getOfflineClientSessionMaxIdleMs);
|
||||
checkRemoteCache(session, offlineClientSessionsCache, this::deriveOfflineClientSessionCacheEntryLifespanOverrideMs, SessionTimeouts::getOfflineClientSessionMaxIdleMs);
|
||||
}
|
||||
|
||||
private <K, V extends SessionEntity> RemoteCache checkRemoteCache(KeycloakSession session, Cache<K, SessionEntityWrapper<V>> ispnCache, RemoteCacheInvoker.MaxIdleTimeLoader maxIdleLoader,
|
||||
private <K, V extends SessionEntity> RemoteCache checkRemoteCache(KeycloakSession session, Cache<K, SessionEntityWrapper<V>> ispnCache,
|
||||
SessionFunction<V> lifespanMsLoader, SessionFunction<V> maxIdleTimeMsLoader) {
|
||||
Set<RemoteStore> remoteStores = InfinispanUtil.getRemoteStores(ispnCache);
|
||||
|
||||
|
@ -363,7 +353,7 @@ public class InfinispanUserSessionProviderFactory implements UserSessionProvider
|
|||
throw new IllegalStateException("No remote cache available for the infinispan cache: " + ispnCache.getName());
|
||||
}
|
||||
|
||||
remoteCacheInvoker.addRemoteCache(ispnCache.getName(), remoteCache, maxIdleLoader);
|
||||
remoteCacheInvoker.addRemoteCache(ispnCache.getName(), remoteCache);
|
||||
|
||||
Runnable onFailover = null;
|
||||
if (useCaches && MultiSiteUtils.isPersistentSessionsEnabled()) {
|
||||
|
|
|
@ -51,12 +51,11 @@ public class RemoteCacheInvoker {
|
|||
|
||||
public static final Logger logger = Logger.getLogger(RemoteCacheInvoker.class);
|
||||
|
||||
private final Map<String, RemoteCacheContext> remoteCaches = new HashMap<>();
|
||||
private final Map<String, RemoteCache> remoteCaches = new HashMap<>();
|
||||
|
||||
|
||||
public void addRemoteCache(String cacheName, RemoteCache remoteCache, MaxIdleTimeLoader maxIdleLoader) {
|
||||
RemoteCacheContext ctx = new RemoteCacheContext(remoteCache, maxIdleLoader);
|
||||
remoteCaches.put(cacheName, ctx);
|
||||
public void addRemoteCache(String cacheName, RemoteCache remoteCache) {
|
||||
remoteCaches.put(cacheName, remoteCache);
|
||||
}
|
||||
|
||||
public Set<String> getRemoteCacheNames() {
|
||||
|
@ -65,8 +64,8 @@ public class RemoteCacheInvoker {
|
|||
|
||||
|
||||
public <K, V extends SessionEntity> void runTask(KeycloakSession kcSession, RealmModel realm, String cacheName, K key, MergedUpdate<V> task, SessionEntityWrapper<V> sessionWrapper) {
|
||||
RemoteCacheContext context = remoteCaches.get(cacheName);
|
||||
if (context == null) {
|
||||
RemoteCache remoteCache = remoteCaches.get(cacheName);
|
||||
if (remoteCache == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -80,10 +79,7 @@ public class RemoteCacheInvoker {
|
|||
return;
|
||||
}
|
||||
|
||||
long loadedMaxIdleTimeMs = context.maxIdleTimeLoader.getMaxIdleTimeMs(realm);
|
||||
|
||||
// Increase the timeout to ensure that entry won't expire on remoteCache in case that write of some entities to remoteCache is postponed (eg. userSession.lastSessionRefresh)
|
||||
final long maxIdleTimeMs = loadedMaxIdleTimeMs + 1800000;
|
||||
long maxIdleTimeMs = getMaxIdleTimeMs(task);
|
||||
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.tracef("Running task '%s' on remote cache '%s' . Key is '%s'", operation, cacheName, key);
|
||||
|
@ -94,7 +90,7 @@ public class RemoteCacheInvoker {
|
|||
Retry.executeWithBackoff((int iteration) -> {
|
||||
|
||||
try {
|
||||
runOnRemoteCache(topology, context.remoteCache, maxIdleTimeMs, key, task, sessionWrapper);
|
||||
runOnRemoteCache(topology, remoteCache, maxIdleTimeMs, key, task, sessionWrapper);
|
||||
} catch (HotRodClientException re) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debugf(re, "Failed running task '%s' on remote cache '%s' . Key: '%s', iteration '%s'. Will try to retry the task",
|
||||
|
@ -108,6 +104,14 @@ public class RemoteCacheInvoker {
|
|||
}, 10, 10);
|
||||
}
|
||||
|
||||
private static <V extends SessionEntity> long getMaxIdleTimeMs(MergedUpdate<V> task) {
|
||||
long maxIdleTimeMs = task.getMaxIdleTimeMs();
|
||||
if (maxIdleTimeMs > 0) {
|
||||
// Increase the timeout to ensure that entry won't expire on remoteCache in case that write of some entities to remoteCache is postponed (eg. userSession.lastSessionRefresh)
|
||||
maxIdleTimeMs += 1800000;
|
||||
}
|
||||
return maxIdleTimeMs;
|
||||
}
|
||||
|
||||
private <K, V extends SessionEntity> void runOnRemoteCache(TopologyInfo topology, RemoteCache<K, SessionEntityWrapper<V>> remoteCache, long maxIdleMs, K key, MergedUpdate<V> task, SessionEntityWrapper<V> sessionWrapper) {
|
||||
SessionUpdateTask.CacheOperation operation = task.getOperation();
|
||||
|
@ -195,27 +199,4 @@ public class RemoteCacheInvoker {
|
|||
private String logTopologyData(TopologyInfo topology, int iteration) {
|
||||
return topology.toString() + ", replaceIteration: " + iteration;
|
||||
}
|
||||
|
||||
|
||||
private static class RemoteCacheContext {
|
||||
|
||||
private final RemoteCache remoteCache;
|
||||
private final MaxIdleTimeLoader maxIdleTimeLoader;
|
||||
|
||||
public RemoteCacheContext(RemoteCache remoteCache, MaxIdleTimeLoader maxIdleLoader) {
|
||||
this.remoteCache = remoteCache;
|
||||
this.maxIdleTimeLoader = maxIdleLoader;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@FunctionalInterface
|
||||
public interface MaxIdleTimeLoader {
|
||||
|
||||
long getMaxIdleTimeMs(RealmModel realm);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue