Skip to content

Commit 4c32eaa

Browse files
author
Myron Scott
committed
Simplify and synchronized the way config is updated or checked
1 parent ddd389b commit 4c32eaa

File tree

7 files changed

+284
-79
lines changed

7 files changed

+284
-79
lines changed

tc-server/src/main/java/com/tc/config/ServerConfigurationManager.java

Lines changed: 257 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
*/
1818
package com.tc.config;
1919

20-
2120
import com.tc.classloader.ServiceLocator;
2221
import com.tc.productinfo.ProductInfo;
2322
import com.tc.properties.TCPropertiesImpl;
@@ -28,34 +27,42 @@
2827
import java.io.ByteArrayInputStream;
2928
import java.io.InputStream;
3029
import java.nio.charset.StandardCharsets;
31-
import java.util.Collection;
3230
import java.util.Collections;
3331
import java.util.HashMap;
3432
import java.util.Map;
3533
import java.util.Objects;
3634
import java.util.Properties;
3735
import org.terracotta.configuration.ConfigurationException;
3836
import com.tc.text.PrettyPrintable;
37+
import java.io.Closeable;
38+
import java.io.File;
39+
import java.net.InetSocketAddress;
3940
import java.util.List;
41+
import java.util.concurrent.locks.Lock;
42+
import java.util.concurrent.locks.ReentrantLock;
43+
import java.util.stream.Collectors;
44+
import org.slf4j.Logger;
45+
import org.slf4j.LoggerFactory;
46+
import org.terracotta.configuration.FailoverBehavior;
47+
import org.terracotta.entity.ServiceProviderConfiguration;
4048

4149
public class ServerConfigurationManager implements PrettyPrintable {
4250

43-
private final ConfigurationProvider configurationProvider;
51+
private final Logger LOGGER = LoggerFactory.getLogger(ServerConfigurationManager.class);
52+
private final CachingConfigurationProvider configurationProvider;
53+
private ServerConfiguration thisServer;
4454
private final ServiceLocator serviceLocator;
4555
private final List<String> startUpArgs;
4656
private final ProductInfo productInfo;
4757

48-
private Configuration configuration;
49-
private ServerConfiguration serverConfiguration;
50-
5158
public ServerConfigurationManager(ConfigurationProvider configurationProvider,
52-
ServiceLocator classLoader,
53-
List<String> startUpArgs) {
59+
ServiceLocator classLoader,
60+
List<String> startUpArgs) {
5461
Objects.requireNonNull(configurationProvider);
5562
Objects.requireNonNull(classLoader);
5663
Objects.requireNonNull(startUpArgs);
5764

58-
this.configurationProvider = configurationProvider;
65+
this.configurationProvider = new CachingConfigurationProvider(configurationProvider);
5966
this.serviceLocator = classLoader;
6067
this.startUpArgs = startUpArgs;
6168
this.productInfo = generateProductInfo(serviceLocator);
@@ -70,18 +77,24 @@ public ProductInfo getProductInfo() {
7077
}
7178

7279
public void initialize() throws ConfigurationException {
73-
this.configurationProvider.initialize(this.startUpArgs);
74-
75-
this.configuration = configurationProvider.getConfiguration();
76-
if (this.configuration == null) {
77-
throw new ConfigurationException("unable to determine server configuration");
78-
}
80+
Lock lock = this.configurationProvider.lockAndInitialize(this.startUpArgs);
7981

80-
this.serverConfiguration = this.configuration.getServerConfiguration();
81-
if (this.serverConfiguration == null) {
82-
throw new ConfigurationException("unable to determine server configuration");
82+
try {
83+
Configuration configuration = configurationProvider.getConfiguration();
84+
if (configuration == null) {
85+
throw new ConfigurationException("unable to determine server configuration");
86+
}
87+
88+
ServerConfiguration base = configuration.getServerConfiguration();
89+
if (base == null) {
90+
throw new ConfigurationException("unable to determine server configuration");
91+
}
92+
thisServer = new StableServerConfiguration(base);
93+
94+
processTcProperties(configuration.getTcProperties());
95+
} finally {
96+
lock.unlock();
8397
}
84-
processTcProperties(configuration.getTcProperties());
8598
}
8699

87100
public void close() {
@@ -93,69 +106,265 @@ public String[] getProcessArguments() {
93106
}
94107

95108
public ServerConfiguration getServerConfiguration() {
96-
return this.serverConfiguration;
109+
return thisServer;
97110
}
98111

99112
public GroupConfiguration getGroupConfiguration() {
100-
List<ServerConfiguration> serverConfigurationMap = configuration.getServerConfigurations();
101-
return new GroupConfiguration(serverConfigurationMap, this.serverConfiguration.getName());
113+
List<ServerConfiguration> serverConfigurationMap = configurationProvider.getStableServerConfigurations();
114+
return new GroupConfiguration(serverConfigurationMap, getServerConfiguration().getName());
102115
}
103-
116+
104117
public InputStream rawConfigFile() {
105-
String text = configuration.getRawConfiguration();
106-
return new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8));
118+
try (LockedConfiguration config = configurationProvider.getLockedConfiguration()) {
119+
String text = config.getRawConfiguration();
120+
return new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8));
121+
}
107122
}
108123

109124
public String rawConfigString() {
110-
return configuration.getRawConfiguration();
125+
try (LockedConfiguration config = configurationProvider.getLockedConfiguration()) {
126+
return config.getRawConfiguration();
127+
}
111128
}
112129

113130
public String[] allCurrentlyKnownServers() {
114131
return getGroupConfiguration().getMembers();
115132
}
116-
133+
134+
public boolean isConsistentStartup() {
135+
try (LockedConfiguration config = configurationProvider.getLockedConfiguration()) {
136+
return config.isConsistentStartup();
137+
}
138+
}
139+
117140
public boolean isPartialConfiguration() {
118-
return this.configuration.isPartialConfiguration();
141+
try (LockedConfiguration config = configurationProvider.getLockedConfiguration()) {
142+
return config.isPartialConfiguration();
143+
}
144+
}
145+
146+
public FailoverBehavior getFailoverPriority() {
147+
try (LockedConfiguration config = configurationProvider.getLockedConfiguration()) {
148+
return config.getFailoverPriority();
149+
}
150+
}
151+
152+
public <T> List<T> getExtendedConfiguration(Class<T> type) {
153+
try (LockedConfiguration config = configurationProvider.getLockedConfiguration()) {
154+
return config.getExtendedConfiguration(type);
155+
}
119156
}
120157

158+
public List<ServiceProviderConfiguration> getServiceConfigurations() {
159+
try (LockedConfiguration config = configurationProvider.getLockedConfiguration()) {
160+
return config.getServiceConfigurations();
161+
}
162+
}
163+
121164
public ServiceLocator getServiceLocator() {
122165
return this.serviceLocator;
123166
}
124167

125-
public Configuration getConfiguration() {
126-
return configuration;
127-
}
128-
129168
public ConfigurationProvider getConfigurationProvider() {
130-
return configurationProvider;
131-
}
132-
133-
private Map<String, ServerConfiguration> getServerConfigurationMap(Collection<ServerConfiguration> servers) {
134-
Map<String, ServerConfiguration> serverConfigurationMap = new HashMap<>();
135-
for (ServerConfiguration server : servers) {
136-
if (server.getName() != null) {
137-
serverConfigurationMap.put(server.getName(), server);
138-
}
139-
}
140-
return serverConfigurationMap;
169+
return configurationProvider.delegateProvider;
141170
}
142171

143172
private static void processTcProperties(Properties tcProperties) {
144173
Map<String, String> propMap = new HashMap<>();
145174

146175
if (tcProperties != null) {
147-
tcProperties.forEach((k, v)->propMap.put(k.toString().trim(), v.toString().trim()));
176+
tcProperties.forEach((k, v) -> propMap.put(k.toString().trim(), v.toString().trim()));
148177
}
149178

150179
TCPropertiesImpl.getProperties().overwriteTcPropertiesFromConfig(propMap);
151180
}
152181

153182
@Override
154183
public Map<String, ?> getStateMap() {
155-
if (configuration instanceof PrettyPrintable) {
156-
return ((PrettyPrintable)configuration).getStateMap();
157-
} else {
158-
return Collections.emptyMap();
184+
try (LockedConfiguration config = configurationProvider.getLockedConfiguration()) {
185+
if (config instanceof PrettyPrintable) {
186+
return ((PrettyPrintable) config).getStateMap();
187+
} else {
188+
return Collections.emptyMap();
189+
}
190+
}
191+
}
192+
193+
private static class LockedConfiguration implements Configuration, Closeable {
194+
private final Configuration delegate;
195+
private final Lock close;
196+
197+
public LockedConfiguration(Configuration delegate, Lock close) {
198+
this.delegate = delegate;
199+
this.close = close;
200+
}
201+
202+
public void close() {
203+
close.unlock();
204+
}
205+
206+
@Override
207+
public ServerConfiguration getServerConfiguration() throws ConfigurationException {
208+
return delegate.getServerConfiguration();
209+
}
210+
211+
@Override
212+
public List<ServerConfiguration> getServerConfigurations() {
213+
return delegate.getServerConfigurations();
214+
}
215+
216+
@Override
217+
public List<ServiceProviderConfiguration> getServiceConfigurations() {
218+
return delegate.getServiceConfigurations();
219+
}
220+
221+
@Override
222+
public <T> List<T> getExtendedConfiguration(Class<T> type) {
223+
return delegate.getExtendedConfiguration(type);
224+
}
225+
226+
@Override
227+
public String getRawConfiguration() {
228+
return delegate.getRawConfiguration();
229+
}
230+
231+
@Override
232+
public Properties getTcProperties() {
233+
return delegate.getTcProperties();
234+
}
235+
236+
@Override
237+
public FailoverBehavior getFailoverPriority() {
238+
return delegate.getFailoverPriority();
239+
}
240+
241+
@Override
242+
public boolean isConsistentStartup() {
243+
return delegate.isConsistentStartup();
244+
}
245+
246+
@Override
247+
public boolean isPartialConfiguration() {
248+
return delegate.isPartialConfiguration();
249+
}
250+
}
251+
252+
private static final class CachingConfigurationProvider implements ConfigurationProvider {
253+
254+
private final ConfigurationProvider delegateProvider;
255+
private final Lock lock = new ReentrantLock();
256+
257+
public CachingConfigurationProvider(ConfigurationProvider delegateProvider) {
258+
this.delegateProvider = delegateProvider;
259+
}
260+
261+
List<ServerConfiguration> getStableServerConfigurations() {
262+
lock.lock();
263+
try {
264+
return delegateProvider.getConfiguration().getServerConfigurations().stream().map(StableServerConfiguration::new).collect(Collectors.toList());
265+
} finally {
266+
lock.unlock();
267+
}
268+
}
269+
270+
Lock lockAndInitialize(List<String> configurationParams) throws ConfigurationException {
271+
lock.lock();
272+
initialize(configurationParams);
273+
return lock;
274+
}
275+
276+
@Override
277+
public void initialize(List<String> configurationParams) throws ConfigurationException {
278+
delegateProvider.initialize(configurationParams);
279+
}
280+
281+
public LockedConfiguration getLockedConfiguration() {
282+
lock.lock();
283+
return new LockedConfiguration(delegateProvider.getConfiguration(), lock);
284+
}
285+
286+
@Override
287+
public Configuration getConfiguration() {
288+
lock.lock();
289+
try {
290+
return delegateProvider.getConfiguration();
291+
} finally {
292+
lock.unlock();
293+
}
294+
}
295+
296+
@Override
297+
public String getConfigurationParamsDescription() {
298+
return delegateProvider.getConfigurationParamsDescription();
299+
}
300+
301+
@Override
302+
public void close() {
303+
delegateProvider.close();
304+
}
305+
306+
@Override
307+
public byte[] getSyncData() {
308+
return delegateProvider.getSyncData();
309+
}
310+
311+
@Override
312+
public void sync(byte[] syncData) {
313+
lock.lock();
314+
try {
315+
delegateProvider.sync(syncData);
316+
} finally {
317+
lock.unlock();
318+
}
319+
}
320+
}
321+
322+
private static class StableServerConfiguration implements ServerConfiguration {
323+
324+
private final InetSocketAddress tsaPort;
325+
private final InetSocketAddress groupPort;
326+
private final String host;
327+
private final String name;
328+
private final int reconnectWindow;
329+
private final File logDir;
330+
331+
public StableServerConfiguration(ServerConfiguration base) {
332+
tsaPort = base.getTsaPort();
333+
groupPort = base.getGroupPort();
334+
host = base.getHost();
335+
name = base.getName();
336+
reconnectWindow = base.getClientReconnectWindow();
337+
logDir = base.getLogsLocation();
338+
}
339+
340+
@Override
341+
public InetSocketAddress getTsaPort() {
342+
return tsaPort;
343+
}
344+
345+
@Override
346+
public InetSocketAddress getGroupPort() {
347+
return groupPort;
348+
}
349+
350+
@Override
351+
public String getHost() {
352+
return host;
353+
}
354+
355+
@Override
356+
public String getName() {
357+
return name;
358+
}
359+
360+
@Override
361+
public int getClientReconnectWindow() {
362+
return reconnectWindow;
363+
}
364+
365+
@Override
366+
public File getLogsLocation() {
367+
return logDir;
159368
}
160369
}
161370
}

0 commit comments

Comments
 (0)