From 7edafd86f5a5526e788cb54b7df7221310bff26f Mon Sep 17 00:00:00 2001 From: Myron Scott Date: Mon, 30 Sep 2024 15:06:31 -0700 Subject: [PATCH] Simplify and synchronized the way config is updated or checked --- .../tc/config/ServerConfigurationManager.java | 191 ++++++++++++++---- 1 file changed, 150 insertions(+), 41 deletions(-) diff --git a/tc-server/src/main/java/com/tc/config/ServerConfigurationManager.java b/tc-server/src/main/java/com/tc/config/ServerConfigurationManager.java index 18c34b1b6d..3310dc3cf5 100644 --- a/tc-server/src/main/java/com/tc/config/ServerConfigurationManager.java +++ b/tc-server/src/main/java/com/tc/config/ServerConfigurationManager.java @@ -17,7 +17,6 @@ */ package com.tc.config; - import com.tc.classloader.ServiceLocator; import com.tc.productinfo.ProductInfo; import com.tc.properties.TCPropertiesImpl; @@ -28,7 +27,6 @@ import java.io.ByteArrayInputStream; import java.io.InputStream; import java.nio.charset.StandardCharsets; -import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -36,26 +34,33 @@ import java.util.Properties; import org.terracotta.configuration.ConfigurationException; import com.tc.text.PrettyPrintable; +import java.io.File; +import java.net.InetSocketAddress; import java.util.List; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.stream.Collectors; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ServerConfigurationManager implements PrettyPrintable { - private final ConfigurationProvider configurationProvider; + private final Logger LOGGER = LoggerFactory.getLogger(ServerConfigurationManager.class); + private final CachingConfigurationProvider configurationProvider; + private ServerConfiguration thisServer; + private GroupConfiguration groupConfig; private final ServiceLocator serviceLocator; private final List startUpArgs; private final ProductInfo productInfo; - private Configuration configuration; - private ServerConfiguration serverConfiguration; - public ServerConfigurationManager(ConfigurationProvider configurationProvider, - ServiceLocator classLoader, - List startUpArgs) { + ServiceLocator classLoader, + List startUpArgs) { Objects.requireNonNull(configurationProvider); Objects.requireNonNull(classLoader); Objects.requireNonNull(startUpArgs); - this.configurationProvider = configurationProvider; + this.configurationProvider = new CachingConfigurationProvider(configurationProvider); this.serviceLocator = classLoader; this.startUpArgs = startUpArgs; this.productInfo = generateProductInfo(serviceLocator); @@ -70,18 +75,27 @@ public ProductInfo getProductInfo() { } public void initialize() throws ConfigurationException { - this.configurationProvider.initialize(this.startUpArgs); - - this.configuration = configurationProvider.getConfiguration(); - if (this.configuration == null) { - throw new ConfigurationException("unable to determine server configuration"); - } + Lock lock = this.configurationProvider.lockAndInitialize(this.startUpArgs); + + try { + Configuration configuration = configurationProvider.getConfiguration(); + if (configuration == null) { + throw new ConfigurationException("unable to determine server configuration"); + } + + ServerConfiguration base = configuration.getServerConfiguration(); + if (base == null) { + throw new ConfigurationException("unable to determine server configuration"); + } + thisServer = new StableServerConfiguration(base); + + List serverConfigurationMap = getConfiguration().getServerConfigurations().stream().map(StableServerConfiguration::new).collect(Collectors.toList()); + groupConfig = new GroupConfiguration(serverConfigurationMap, getServerConfiguration().getName()); - this.serverConfiguration = this.configuration.getServerConfiguration(); - if (this.serverConfiguration == null) { - throw new ConfigurationException("unable to determine server configuration"); + processTcProperties(configuration.getTcProperties()); + } finally { + lock.unlock(); } - processTcProperties(configuration.getTcProperties()); } public void close() { @@ -93,21 +107,20 @@ public String[] getProcessArguments() { } public ServerConfiguration getServerConfiguration() { - return this.serverConfiguration; + return thisServer; } public GroupConfiguration getGroupConfiguration() { - List serverConfigurationMap = configuration.getServerConfigurations(); - return new GroupConfiguration(serverConfigurationMap, this.serverConfiguration.getName()); + return groupConfig; } - + public InputStream rawConfigFile() { - String text = configuration.getRawConfiguration(); + String text = getConfiguration().getRawConfiguration(); return new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8)); } public String rawConfigString() { - return configuration.getRawConfiguration(); + return getConfiguration().getRawConfiguration(); } public String[] allCurrentlyKnownServers() { @@ -115,7 +128,7 @@ public String[] allCurrentlyKnownServers() { } public boolean isPartialConfiguration() { - return this.configuration.isPartialConfiguration(); + return getConfiguration().isPartialConfiguration(); } public ServiceLocator getServiceLocator() { @@ -123,28 +136,18 @@ public ServiceLocator getServiceLocator() { } public Configuration getConfiguration() { - return configuration; + return configurationProvider.getConfiguration(); } public ConfigurationProvider getConfigurationProvider() { - return configurationProvider; - } - - private Map getServerConfigurationMap(Collection servers) { - Map serverConfigurationMap = new HashMap<>(); - for (ServerConfiguration server : servers) { - if (server.getName() != null) { - serverConfigurationMap.put(server.getName(), server); - } - } - return serverConfigurationMap; + return configurationProvider.delegateProvider; } private static void processTcProperties(Properties tcProperties) { Map propMap = new HashMap<>(); if (tcProperties != null) { - tcProperties.forEach((k, v)->propMap.put(k.toString().trim(), v.toString().trim())); + tcProperties.forEach((k, v) -> propMap.put(k.toString().trim(), v.toString().trim())); } TCPropertiesImpl.getProperties().overwriteTcPropertiesFromConfig(propMap); @@ -152,10 +155,116 @@ private static void processTcProperties(Properties tcProperties) { @Override public Map getStateMap() { - if (configuration instanceof PrettyPrintable) { - return ((PrettyPrintable)configuration).getStateMap(); + Configuration config = getConfiguration(); + if (config instanceof PrettyPrintable) { + return ((PrettyPrintable) config).getStateMap(); } else { return Collections.emptyMap(); } } + + private static final class CachingConfigurationProvider implements ConfigurationProvider { + + private final ConfigurationProvider delegateProvider; + private final Lock lock = new ReentrantLock(); + + public CachingConfigurationProvider(ConfigurationProvider delegateProvider) { + this.delegateProvider = delegateProvider; + } + + Lock lockAndInitialize(List configurationParams) throws ConfigurationException { + lock.lock(); + initialize(configurationParams); + return lock; + } + + @Override + public void initialize(List configurationParams) throws ConfigurationException { + delegateProvider.initialize(configurationParams); + } + + @Override + public Configuration getConfiguration() { + lock.lock(); + try { + return delegateProvider.getConfiguration(); + } finally { + lock.unlock(); + } + } + + @Override + public String getConfigurationParamsDescription() { + return delegateProvider.getConfigurationParamsDescription(); + } + + @Override + public void close() { + delegateProvider.close(); + } + + @Override + public byte[] getSyncData() { + return delegateProvider.getSyncData(); + } + + @Override + public void sync(byte[] syncData) { + lock.lock(); + try { + delegateProvider.sync(syncData); + } finally { + lock.unlock(); + } + } + } + + private static class StableServerConfiguration implements ServerConfiguration { + + private final InetSocketAddress tsaPort; + private final InetSocketAddress groupPort; + private final String host; + private final String name; + private final int reconnectWindow; + private final File logDir; + + public StableServerConfiguration(ServerConfiguration base) { + tsaPort = base.getTsaPort(); + groupPort = base.getGroupPort(); + host = base.getHost(); + name = base.getName(); + reconnectWindow = base.getClientReconnectWindow(); + logDir = base.getLogsLocation(); + } + + @Override + public InetSocketAddress getTsaPort() { + return tsaPort; + } + + @Override + public InetSocketAddress getGroupPort() { + return groupPort; + } + + @Override + public String getHost() { + return host; + } + + @Override + public String getName() { + return name; + } + + @Override + public int getClientReconnectWindow() { + return reconnectWindow; + } + + @Override + public File getLogsLocation() { + return logDir; + } + } }