Fix various performance issues

- Avoiding read attempts for stores that do not exist (AbstractStore).
- Use of ReadWrite locks (everything withLockedFileForRead or withLockedFileForWrite)
- Caching of JAXB Context (TypedStoreContext.java)
- Avoid unnecessary writes to the UserGroupCache

Committed-by: Eduard Heimbuch <eduard.heimbuch@cloudogu.com>
Co-authored-by: René Pfeuffer <rene.pfeuffer@cloudogu.com>
This commit is contained in:
Rene Pfeuffer
2023-03-02 11:05:04 +01:00
committed by SCM-Manager
parent 8cef21e32c
commit 83c7e0523d
15 changed files with 106 additions and 48 deletions

View File

@@ -60,14 +60,14 @@ public class DefaultGroupCollector implements GroupCollector {
private final Cache<String, Set<String>> cache;
private final Set<GroupResolver> groupResolvers;
private final ConfigurationStoreFactory configurationStoreFactory;
private final ConfigurationStore<UserGroupCache> store;
@Inject
public DefaultGroupCollector(GroupDAO groupDAO, CacheManager cacheManager, Set<GroupResolver> groupResolvers, ConfigurationStoreFactory configurationStoreFactory) {
this.groupDAO = groupDAO;
this.cache = cacheManager.getCache(CACHE_NAME);
this.groupResolvers = groupResolvers;
this.configurationStoreFactory = configurationStoreFactory;
this.store = configurationStoreFactory.withType(UserGroupCache.class).withName("user-group-cache").build();
}
@Override
@@ -87,29 +87,25 @@ public class DefaultGroupCollector implements GroupCollector {
Set<String> groups = builder.build();
LOG.debug("collected following groups for principal {}: {}", principal, groups);
ConfigurationStore<UserGroupCache> store = createStore();
UserGroupCache persistentCache = getPersistentCache(store);
persistentCache.put(principal, groups);
store.set(persistentCache);
UserGroupCache persistentCache = getPersistentCache();
if (persistentCache.put(principal, groups)) {
store.set(persistentCache);
}
return groups;
}
@Override
public Set<String> fromLastLoginPlusInternal(String principal) {
Set<String> cached = new HashSet<>(getPersistentCache(createStore()).get(principal));
Set<String> cached = new HashSet<>(getPersistentCache().get(principal));
computeInternalGroups(principal).forEach(cached::add);
return cached;
}
private static UserGroupCache getPersistentCache(ConfigurationStore<UserGroupCache> store) {
private UserGroupCache getPersistentCache() {
return store.getOptional().orElseGet(UserGroupCache::new);
}
private ConfigurationStore<UserGroupCache> createStore() {
return configurationStoreFactory.withType(UserGroupCache.class).withName("user-group-cache").build();
}
@Subscribe(async = false)
public void clearCacheOnLogOut(LogoutEvent event) {
String principal = event.getPrimaryPrincipal();

View File

@@ -49,10 +49,14 @@ class UserGroupCache {
return cache.getOrDefault(user, emptySet());
}
void put(String user, Set<String> groups) {
boolean put(String user, Set<String> groups) {
if (cache == null) {
cache = new HashMap<>();
}
if (groups.equals(cache.get(user))) {
return false;
}
cache.put(user, groups);
return true;
}
}

View File

@@ -92,7 +92,7 @@ abstract class DifferentiateBetweenConfigAndConfigEntryUpdateStep {
private void updateSingleFile(Path configFile) {
LOG.info("Updating config entry file: {}", configFile);
Document configEntryDocument = compute(() -> readAsXmlDocument(configFile)).withLockedFile(configFile);
Document configEntryDocument = compute(() -> readAsXmlDocument(configFile)).withLockedFileForRead(configFile);
configEntryDocument.getDocumentElement().setAttribute("type", "config-entry");