From 64174598087c84545aa0185f04445a4b49b17f4c Mon Sep 17 00:00:00 2001 From: Rui Gu Date: Thu, 20 Apr 2017 23:06:40 +0100 Subject: [PATCH 1/6] I should use File.separator for directory separation in path --- redisson/src/test/java/org/redisson/ClusterRunner.java | 2 +- redisson/src/test/java/org/redisson/RedisRunner.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/redisson/src/test/java/org/redisson/ClusterRunner.java b/redisson/src/test/java/org/redisson/ClusterRunner.java index abca5b170..c02d58ea8 100644 --- a/redisson/src/test/java/org/redisson/ClusterRunner.java +++ b/redisson/src/test/java/org/redisson/ClusterRunner.java @@ -50,7 +50,7 @@ public class ClusterRunner { ArrayList processes = new ArrayList<>(); for (RedisRunner runner : nodes.keySet()) { List options = getClusterConfig(runner); - String confFile = runner.dir() + File.separatorChar + nodes.get(runner) + ".conf"; + String confFile = runner.dir() + File.separator + nodes.get(runner) + ".conf"; System.out.println("WRITING CONFIG: for " + nodes.get(runner)); try (PrintWriter printer = new PrintWriter(new FileWriter(confFile))) { options.stream().forEach((line) -> { diff --git a/redisson/src/test/java/org/redisson/RedisRunner.java b/redisson/src/test/java/org/redisson/RedisRunner.java index 5499bd5ad..1571057e2 100644 --- a/redisson/src/test/java/org/redisson/RedisRunner.java +++ b/redisson/src/test/java/org/redisson/RedisRunner.java @@ -272,7 +272,7 @@ public class RedisRunner { public RedisProcess runAndCheck() throws IOException, InterruptedException, FailedToStartRedisException { List args = new ArrayList(options.values()); if (sentinelFile != null && sentinelFile.length() > 0) { - String confFile = defaultDir + File.pathSeparator + sentinelFile; + String confFile = defaultDir + File.separator + sentinelFile; try (PrintWriter printer = new PrintWriter(new FileWriter(confFile))) { args.stream().forEach((arg) -> { if (arg.contains("--")) { @@ -845,7 +845,7 @@ public class RedisRunner { } public boolean deleteSentinelFile() { - File f = new File(defaultDir + File.pathSeparator + sentinelFile); + File f = new File(defaultDir + File.separator + sentinelFile); if (f.exists()) { System.out.println("REDIS RUNNER: Deleting sentinel config file " + f.getAbsolutePath()); return f.delete(); @@ -863,7 +863,7 @@ public class RedisRunner { } private void makeRandomDefaultDir() { - File f = new File(RedissonRuntimeEnvironment.tempDir + File.pathSeparator + UUID.randomUUID()); + File f = new File(RedissonRuntimeEnvironment.tempDir + File.separator + UUID.randomUUID()); if (f.exists()) { makeRandomDefaultDir(); } else { From 032c53fa421c21fe6dea0eebee482225c47bd1e9 Mon Sep 17 00:00:00 2001 From: Rui Gu Date: Thu, 20 Apr 2017 23:09:02 +0100 Subject: [PATCH 2/6] RedisRunner.dir() should return either user value or default value --- redisson/src/test/java/org/redisson/RedisRunner.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redisson/src/test/java/org/redisson/RedisRunner.java b/redisson/src/test/java/org/redisson/RedisRunner.java index 1571057e2..fecfe17f1 100644 --- a/redisson/src/test/java/org/redisson/RedisRunner.java +++ b/redisson/src/test/java/org/redisson/RedisRunner.java @@ -828,7 +828,7 @@ public class RedisRunner { } public String dir() { - return this.path; + return isRandomDir() ? defaultDir() : this.path; } public String getInitialBindAddr() { From 010d780cabebe48d8fac8fc659a19e44c56e8121 Mon Sep 17 00:00:00 2001 From: Rui Gu Date: Thu, 20 Apr 2017 23:13:12 +0100 Subject: [PATCH 3/6] RedisRunner.RedisProcess.stop no longer throws Exception --- .../test/java/org/redisson/RedisRunner.java | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/redisson/src/test/java/org/redisson/RedisRunner.java b/redisson/src/test/java/org/redisson/RedisRunner.java index fecfe17f1..6f9190f8d 100644 --- a/redisson/src/test/java/org/redisson/RedisRunner.java +++ b/redisson/src/test/java/org/redisson/RedisRunner.java @@ -290,10 +290,7 @@ public class RedisRunner { throw new FailedToStartRedisException(); } Runtime.getRuntime().addShutdownHook(new Thread(() -> { - try { - rp.stop(); - } catch (InterruptedException ex) { - } + rp.stop(); })); return rp; } @@ -884,17 +881,36 @@ public class RedisRunner { this.runner = runner; } - public int stop() throws InterruptedException { + public int stop() { if (runner.isNosave() && !runner.isRandomDir()) { RedisClient c = createDefaultRedisClientInstance(); RedisConnection connection = c.connect(); - connection.async(new RedisStrictCommand("SHUTDOWN", "NOSAVE", new VoidReplayConvertor())) - .await(3, TimeUnit.SECONDS); + try { + connection.async(new RedisStrictCommand("SHUTDOWN", "NOSAVE", new VoidReplayConvertor())) + .await(3, TimeUnit.SECONDS); + } catch (InterruptedException interruptedException) { + //shutdown via command failed, lets wait and kill it later. + } c.shutdown(); connection.closeAsync().syncUninterruptibly(); } - redisProcess.destroy(); - int exitCode = redisProcess.isAlive() ? redisProcess.waitFor() : redisProcess.exitValue(); + Process p = redisProcess; + p.destroy(); + boolean normalTermination = false; + try { + normalTermination = p.waitFor(5, TimeUnit.SECONDS); + } catch (InterruptedException ex) { + //OK lets hurry up by force kill; + } + if (!normalTermination) { + p = p.destroyForcibly(); + } + cleanup(); + int exitCode = p.exitValue(); + return exitCode == 1 && RedissonRuntimeEnvironment.isWindows ? 0 : exitCode; + } + + private void cleanup() { if (runner.isSentinel()) { runner.deleteSentinelFile(); } @@ -904,9 +920,8 @@ public class RedisRunner { if (runner.isRandomDir()) { runner.deleteDBfileDir(); } - return exitCode == 1 && RedissonRuntimeEnvironment.isWindows ? 0 : exitCode; } - + public Process getRedisProcess() { return redisProcess; } From cae00f645d3dcb641d9133079df7f6f967742925 Mon Sep 17 00:00:00 2001 From: Rui Gu Date: Thu, 20 Apr 2017 23:14:54 +0100 Subject: [PATCH 4/6] masters map renamed to slaveMasters to avoid confusion --- redisson/src/test/java/org/redisson/ClusterRunner.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/redisson/src/test/java/org/redisson/ClusterRunner.java b/redisson/src/test/java/org/redisson/ClusterRunner.java index c02d58ea8..aab7f9da2 100644 --- a/redisson/src/test/java/org/redisson/ClusterRunner.java +++ b/redisson/src/test/java/org/redisson/ClusterRunner.java @@ -17,7 +17,7 @@ import java.util.List; public class ClusterRunner { private final LinkedHashMap nodes = new LinkedHashMap<>(); - private final LinkedHashMap masters = new LinkedHashMap<>(); + private final LinkedHashMap slaveMasters = new LinkedHashMap<>(); public ClusterRunner addNode(RedisRunner runner) { nodes.putIfAbsent(runner, getRandomId()); @@ -41,7 +41,7 @@ public class ClusterRunner { addNode(master); for (RedisRunner slave : slaves) { addNode(slave); - masters.put(nodes.get(slave), nodes.get(master)); + slaveMasters.put(nodes.get(slave), nodes.get(master)); } return this; } @@ -82,10 +82,10 @@ public class ClusterRunner { sb.append(me.equals(nodeAddr) ? "myself," : ""); - if (!masters.containsKey(nodeId)) { + if (!slaveMasters.containsKey(nodeId)) { sb.append("master -"); } else { - sb.append("slave ").append(masters.get(nodeId)); + sb.append("slave ").append(slaveMasters.get(nodeId)); } sb.append(" "); sb.append("0").append(" "); From 1f09f262bfb1e36efcbde75b9f4aeac64b357417 Mon Sep 17 00:00:00 2001 From: Rui Gu Date: Thu, 20 Apr 2017 23:15:15 +0100 Subject: [PATCH 5/6] two util methods can be static --- redisson/src/test/java/org/redisson/ClusterRunner.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/redisson/src/test/java/org/redisson/ClusterRunner.java b/redisson/src/test/java/org/redisson/ClusterRunner.java index aab7f9da2..64be2c03d 100644 --- a/redisson/src/test/java/org/redisson/ClusterRunner.java +++ b/redisson/src/test/java/org/redisson/ClusterRunner.java @@ -102,14 +102,14 @@ public class ClusterRunner { return nodeConfig; } - private String getSlots(int index, int groupNum) { + private static String getSlots(int index, int groupNum) { final double t = 16383; int start = index == 0 ? 0 : (int) (t / groupNum * index); int end = index == groupNum - 1 ? (int) t : (int) (t / groupNum * (index + 1)) - 1; return start + "-" + end; } - private String getRandomId() { + private static String getRandomId() { final SecureRandom r = new SecureRandom(); return new BigInteger(160, r).toString(16); } From aaf3166aed1c78a04686807cdf274538f95fa887 Mon Sep 17 00:00:00 2001 From: Rui Gu Date: Thu, 20 Apr 2017 23:15:48 +0100 Subject: [PATCH 6/6] added ClusterRunner.ClusterProcesses --- .../test/java/org/redisson/ClusterRunner.java | 53 ++++++++++++++++--- .../spring/support/SpringNamespaceTest.java | 26 ++++++--- .../support/SpringNamespaceWikiTest.java | 6 +-- 3 files changed, 67 insertions(+), 18 deletions(-) diff --git a/redisson/src/test/java/org/redisson/ClusterRunner.java b/redisson/src/test/java/org/redisson/ClusterRunner.java index 64be2c03d..60dd5afe0 100644 --- a/redisson/src/test/java/org/redisson/ClusterRunner.java +++ b/redisson/src/test/java/org/redisson/ClusterRunner.java @@ -9,6 +9,10 @@ import java.security.SecureRandom; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import org.redisson.misc.BiHashMap; /** * @@ -46,8 +50,8 @@ public class ClusterRunner { return this; } - public List run() throws IOException, InterruptedException, RedisRunner.FailedToStartRedisException { - ArrayList processes = new ArrayList<>(); + public synchronized ClusterProcesses run() throws IOException, InterruptedException, RedisRunner.FailedToStartRedisException { + BiHashMap processes = new BiHashMap<>(); for (RedisRunner runner : nodes.keySet()) { List options = getClusterConfig(runner); String confFile = runner.dir() + File.separator + nodes.get(runner) + ".conf"; @@ -58,15 +62,15 @@ public class ClusterRunner { System.out.println(line); }); } - processes.add(runner.clusterConfigFile(confFile).run()); + processes.put(nodes.get(runner), runner.clusterConfigFile(confFile).run()); } Thread.sleep(1000); - for (RedisRunner.RedisProcess process : processes) { + for (RedisRunner.RedisProcess process : processes.valueSet()) { if (!process.isAlive()) { throw new RedisRunner.FailedToStartRedisException(); } } - return processes; + return new ClusterProcesses(processes); } private List getClusterConfig(RedisRunner runner) { @@ -94,8 +98,10 @@ public class ClusterRunner { : "1").append(" "); sb.append(c + 1).append(" "); sb.append("connected "); - sb.append(getSlots(c, nodes.size())); - c++; + if (!slaveMasters.containsKey(nodeId)) { + sb.append(getSlots(c, nodes.size() - slaveMasters.size())); + c++; + } nodeConfig.add(sb.toString()); } nodeConfig.add("vars currentEpoch 0 lastVoteEpoch 0"); @@ -113,4 +119,37 @@ public class ClusterRunner { final SecureRandom r = new SecureRandom(); return new BigInteger(160, r).toString(16); } + + public static class ClusterProcesses { + private final BiHashMap processes; + + private ClusterProcesses(BiHashMap processes) { + this.processes = processes; + } + + public RedisRunner.RedisProcess getProcess(String nodeId) { + return processes.get(nodeId); + } + + public String getNodeId(RedisRunner.RedisProcess process) { + return processes.reverseGet(process); + } + + public Set getNodes() { + return processes.valueSet(); + } + + public Set getNodeIds() { + return processes.keySet(); + } + + public synchronized Map shutdown() { + return processes + .entrySet() + .stream() + .collect(Collectors.toMap( + e -> e.getKey(), + e -> e.getValue().stop())); + } + } } diff --git a/redisson/src/test/java/org/redisson/spring/support/SpringNamespaceTest.java b/redisson/src/test/java/org/redisson/spring/support/SpringNamespaceTest.java index a2e36842c..588dbbf24 100644 --- a/redisson/src/test/java/org/redisson/spring/support/SpringNamespaceTest.java +++ b/redisson/src/test/java/org/redisson/spring/support/SpringNamespaceTest.java @@ -1,6 +1,8 @@ package org.redisson.spring.support; import java.util.List; +import java.util.Set; +import java.util.concurrent.atomic.AtomicLong; import org.junit.After; import org.junit.AfterClass; import static org.junit.Assert.*; @@ -124,14 +126,24 @@ public class SpringNamespaceTest extends BaseTest { RedisRunner.getDefaultRedisServerInstance().getRedisServerPort(), 2).run(); System.setProperty("sentinel3Address", sentinel3.getRedisServerAddressAndPort()); - + RedisRunner slave = new RedisRunner().randomPort().randomDir().nosave(); ClusterRunner clusterRunner = new ClusterRunner() - .addNode(new RedisRunner().randomPort().randomDir().nosave()) - .addNode(new RedisRunner().randomPort().randomDir().nosave()) - .addNode(new RedisRunner().randomPort().randomDir().nosave()); - List nodes = clusterRunner.run(); - nodes.stream().forEach((node) -> { - System.setProperty("node" + (nodes.indexOf(node) + 1) + "Address", node.getRedisServerAddressAndPort()); + .addNode(new RedisRunner().randomPort().randomDir().nosave(),//master1 + new RedisRunner().randomPort().randomDir().nosave(),//slave1-1 + new RedisRunner().randomPort().randomDir().nosave(),//slave1-2 + slave)//slave1-3 + .addNode(new RedisRunner().randomPort().randomDir().nosave(),//master2 + new RedisRunner().randomPort().randomDir().nosave(),//slave2-1 + new RedisRunner().randomPort().randomDir().nosave())//slave2-2 + .addNode(new RedisRunner().randomPort().randomDir().nosave(),//master3 + new RedisRunner().randomPort().randomDir().nosave(),//slave3-1 + new RedisRunner().randomPort().randomDir().nosave())//slave3-2 + .addNode(slave,//slave1-3 + new RedisRunner().randomPort().randomDir().nosave(),//slave1-3-1 + new RedisRunner().randomPort().randomDir().nosave());//slave1-3-2 + final AtomicLong index = new AtomicLong(0); + clusterRunner.run().getNodes().stream().forEach((node) -> { + System.setProperty("node" + (index.incrementAndGet()) + "Address", node.getRedisServerAddressAndPort()); }); context = new ClassPathXmlApplicationContext("classpath:org/redisson/spring/support/namespace.xml"); diff --git a/redisson/src/test/java/org/redisson/spring/support/SpringNamespaceWikiTest.java b/redisson/src/test/java/org/redisson/spring/support/SpringNamespaceWikiTest.java index df1c38bf3..83d07f1e0 100644 --- a/redisson/src/test/java/org/redisson/spring/support/SpringNamespaceWikiTest.java +++ b/redisson/src/test/java/org/redisson/spring/support/SpringNamespaceWikiTest.java @@ -180,16 +180,14 @@ public class SpringNamespaceWikiTest { .port(6381) .randomDir() .nosave()); - List nodes = clusterRunner.run(); + ClusterRunner.ClusterProcesses cluster = clusterRunner.run(); try { ((ConfigurableApplicationContext) new ClassPathXmlApplicationContext("classpath:org/redisson/spring/support/namespace_wiki_cluster.xml")) .close(); } finally { - for (RedisRunner.RedisProcess node : nodes) { - node.stop(); - } + cluster.shutdown(); } } }