Repository: ignite Updated Branches: refs/heads/master 7cd2a557f -> a9eac55d6
IGNITE-8423 Control utility may block when joining node is watiting for partition map exchange. - Fixes #4018. Signed-off-by: Alexey Goncharuk <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/a9eac55d Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/a9eac55d Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/a9eac55d Branch: refs/heads/master Commit: a9eac55d611559ee8c2d8ae0085dac5706436065 Parents: 7cd2a55 Author: Aleksei Scherbakov <[email protected]> Authored: Thu May 17 20:11:41 2018 +0300 Committer: Alexey Goncharuk <[email protected]> Committed: Thu May 17 20:11:41 2018 +0300 ---------------------------------------------------------------------- bin/control.bat | 2 +- bin/control.sh | 2 +- .../internal/commandline/CommandHandler.java | 59 +++++--- .../ignite/util/GridCommandHandlerTest.java | 150 +++++++++++-------- 4 files changed, 127 insertions(+), 86 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/a9eac55d/bin/control.bat ---------------------------------------------------------------------- diff --git a/bin/control.bat b/bin/control.bat index 8a1e1c8..15d5e6f 100644 --- a/bin/control.bat +++ b/bin/control.bat @@ -104,7 +104,7 @@ if "%OS%" == "Windows_NT" set PROG_NAME=%~nx0% :: call "%SCRIPTS_HOME%\include\setenv.bat" call "%SCRIPTS_HOME%\include\build-classpath.bat" -set CP=%IGNITE_LIBS% +set CP=%IGNITE_LIBS%;%IGNITE_HOME%\libs\optional\ignite-zookeeper\* :: :: Process 'restart'. http://git-wip-us.apache.org/repos/asf/ignite/blob/a9eac55d/bin/control.sh ---------------------------------------------------------------------- diff --git a/bin/control.sh b/bin/control.sh index ad4b14b..e2b75af 100755 --- a/bin/control.sh +++ b/bin/control.sh @@ -54,7 +54,7 @@ fi # . "${SCRIPTS_HOME}"/include/setenv.sh . "${SCRIPTS_HOME}"/include/build-classpath.sh # Will be removed in the binary release. -CP="${IGNITE_LIBS}" +CP="${IGNITE_LIBS}:${IGNITE_HOME}/libs/optional/ignite-zookeeper/*" RANDOM_NUMBER=$("$JAVA" -cp "${CP}" org.apache.ignite.startup.cmdline.CommandLineRandomNumberGenerator) http://git-wip-us.apache.org/repos/asf/ignite/blob/a9eac55d/modules/core/src/main/java/org/apache/ignite/internal/commandline/CommandHandler.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/commandline/CommandHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/commandline/CommandHandler.java index 04578e5..47cc233 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/commandline/CommandHandler.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/commandline/CommandHandler.java @@ -256,6 +256,9 @@ public class CommandHandler { /** */ private Object lastOperationRes; + /** */ + private GridClientConfiguration clientCfg; + /** Check if experimental commands are enabled. Default {@code false}. */ private final boolean enableExperimental = IgniteSystemProperties.getBoolean(IGNITE_ENABLE_EXPERIMENTAL_COMMAND, false); @@ -447,18 +450,6 @@ public class CommandHandler { } /** - * @param client Client. - * @param arg Task argument. - * @return Task result. - * @throws GridClientException If failed to execute task. - */ - private Map<UUID, VisorTxTaskResult> executeTransactionsTask(GridClient client, - VisorTxTaskArg arg) throws GridClientException { - - return executeTask(client, VisorTxTask.class, arg); - } - - /** * * @param client Client. * @param taskCls Task class. @@ -497,8 +488,28 @@ public class CommandHandler { GridClientNode node = null; - if (nodeId == null) - node = getBalancedNode(compute); + if (nodeId == null) { + Collection<GridClientNode> nodes = compute.nodes(GridClientNode::connectable); + + // Prefer node from connect string. + String origAddr = clientCfg.getServers().iterator().next(); + + for (GridClientNode clientNode : nodes) { + Iterator<String> it = F.concat(clientNode.tcpAddresses().iterator(), clientNode.tcpHostNames().iterator()); + + while (it.hasNext()) { + if (origAddr.equals(it.next() + ":" + clientNode.tcpPort())) { + node = clientNode; + + break; + } + } + } + + // Otherwise choose random node. + if (node == null) + node = getBalancedNode(compute); + } else { for (GridClientNode n : compute.nodes()) { if (n.connectable() && nodeId.equals(n.nodeId())) { @@ -1677,12 +1688,12 @@ public class CommandHandler { " delete [consistentId1,consistentId2,....,consistentIdN] [--force]"); } - log("The utility has --cache subcommand to view and control state of caches in cluster."); - log(" More info: control.sh --cache help"); + log(" View caches information in a cluster. For more details type:"); + log(" control.sh --cache help"); nl(); - log("By default commands affecting the cluster require interactive confirmation. "); - log(" --force option can be used to execute commands without prompting for confirmation."); + log("By default commands affecting the cluster require interactive confirmation."); + log("Use --force option to disable it."); nl(); log("Default values:"); @@ -1710,20 +1721,20 @@ public class CommandHandler { return EXIT_CODE_OK; } - GridClientConfiguration cfg = new GridClientConfiguration(); + clientCfg = new GridClientConfiguration(); - cfg.setPingInterval(args.pingInterval()); + clientCfg.setPingInterval(args.pingInterval()); - cfg.setPingTimeout(args.pingTimeout()); + clientCfg.setPingTimeout(args.pingTimeout()); - cfg.setServers(Collections.singletonList(args.host() + ":" + args.port())); + clientCfg.setServers(Collections.singletonList(args.host() + ":" + args.port())); if (!F.isEmpty(args.user())) { - cfg.setSecurityCredentialsProvider( + clientCfg.setSecurityCredentialsProvider( new SecurityCredentialsBasicProvider(new SecurityCredentials(args.user(), args.password()))); } - try (GridClient client = GridClientFactory.start(cfg)) { + try (GridClient client = GridClientFactory.start(clientCfg)) { switch (args.command()) { case ACTIVATE: activate(client); http://git-wip-us.apache.org/repos/asf/ignite/blob/a9eac55d/modules/core/src/test/java/org/apache/ignite/util/GridCommandHandlerTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/util/GridCommandHandlerTest.java b/modules/core/src/test/java/org/apache/ignite/util/GridCommandHandlerTest.java index 2bd14db..80271c7 100644 --- a/modules/core/src/test/java/org/apache/ignite/util/GridCommandHandlerTest.java +++ b/modules/core/src/test/java/org/apache/ignite/util/GridCommandHandlerTest.java @@ -381,69 +381,10 @@ public class GridCommandHandlerTest extends GridCommonAbstractTest { for (Ignite ig : G.allGrids()) assertNotNull(ig.cache(DEFAULT_CACHE_NAME)); - AtomicInteger idx = new AtomicInteger(); - CountDownLatch lockLatch = new CountDownLatch(1); CountDownLatch unlockLatch = new CountDownLatch(1); - IgniteInternalFuture<?> fut = multithreadedAsync(new Runnable() { - @Override public void run() { - int id = idx.getAndIncrement(); - - switch (id) { - case 0: - try (Transaction tx = grid(0).transactions().txStart()) { - grid(0).cache(DEFAULT_CACHE_NAME).putAll(generate(0, 100)); - - lockLatch.countDown(); - - U.awaitQuiet(unlockLatch); - - tx.commit(); - - fail("Commit must fail"); - } - catch (Exception e) { - // No-op. - assertTrue(X.hasCause(e, TransactionRollbackException.class)); - } - - break; - case 1: - U.awaitQuiet(lockLatch); - - doSleep(3000); - - try (Transaction tx = grid(0).transactions().withLabel("label1").txStart(PESSIMISTIC, READ_COMMITTED, Integer.MAX_VALUE, 0)) { - grid(0).cache(DEFAULT_CACHE_NAME).putAll(generate(200, 110)); - - grid(0).cache(DEFAULT_CACHE_NAME).put(0, 0); - } - - break; - case 2: - try (Transaction tx = grid(1).transactions().txStart()) { - U.awaitQuiet(lockLatch); - - grid(1).cache(DEFAULT_CACHE_NAME).put(0, 0); - } - - break; - case 3: - try (Transaction tx = client.transactions().withLabel("label2").txStart(OPTIMISTIC, READ_COMMITTED, 0, 0)) { - U.awaitQuiet(lockLatch); - - client.cache(DEFAULT_CACHE_NAME).putAll(generate(100, 10)); - - client.cache(DEFAULT_CACHE_NAME).put(0, 0); - - tx.commit(); - } - - break; - } - } - }, 4, "tx-thread"); + IgniteInternalFuture<?> fut = startTransactions(lockLatch, unlockLatch); U.awaitQuiet(lockLatch); @@ -518,6 +459,23 @@ public class GridCommandHandlerTest extends GridCommonAbstractTest { }, "--tx", "order", "DURATION"); + // Trigger topology change and test connection. + IgniteInternalFuture<?> startFut = multithreadedAsync(new Runnable() { + @Override public void run() { + try { + startGrid(2); + } + catch (Exception e) { + fail(); + } + } + }, 1, "start-node-thread"); + + doSleep(5000); + + assertEquals(EXIT_CODE_OK, execute(h, "--host", "127.0.0.1", "--port", "11211", "--tx")); + assertEquals(EXIT_CODE_OK, execute(h, "--host", "127.0.0.1", "--port", "11212", "--tx")); + // Test kill by xid. validate(h, map -> { assertEquals(1, map.size()); @@ -533,6 +491,8 @@ public class GridCommandHandlerTest extends GridCommonAbstractTest { unlockLatch.countDown(); + startFut.get(); + fut.get(); } @@ -850,4 +810,74 @@ public class GridCommandHandlerTest extends GridCommonAbstractTest { assertTrue(!testOut.toString().contains("error")); } + + /** + * + * @param lockLatch Lock latch. + * @param unlockLatch Unlock latch. + */ + private IgniteInternalFuture<?> startTransactions(CountDownLatch lockLatch, CountDownLatch unlockLatch) throws Exception { + IgniteEx client = grid("client"); + + AtomicInteger idx = new AtomicInteger(); + + return multithreadedAsync(new Runnable() { + @Override public void run() { + int id = idx.getAndIncrement(); + + switch (id) { + case 0: + try (Transaction tx = grid(0).transactions().txStart()) { + grid(0).cache(DEFAULT_CACHE_NAME).putAll(generate(0, 100)); + + lockLatch.countDown(); + + U.awaitQuiet(unlockLatch); + + tx.commit(); + + fail("Commit must fail"); + } + catch (Exception e) { + // No-op. + assertTrue(X.hasCause(e, TransactionRollbackException.class)); + } + + break; + case 1: + U.awaitQuiet(lockLatch); + + doSleep(3000); + + try (Transaction tx = grid(0).transactions().withLabel("label1").txStart(PESSIMISTIC, READ_COMMITTED, Integer.MAX_VALUE, 0)) { + grid(0).cache(DEFAULT_CACHE_NAME).putAll(generate(200, 110)); + + grid(0).cache(DEFAULT_CACHE_NAME).put(0, 0); + } + + break; + case 2: + try (Transaction tx = grid(1).transactions().txStart()) { + U.awaitQuiet(lockLatch); + + grid(1).cache(DEFAULT_CACHE_NAME).put(0, 0); + } + + break; + case 3: + try (Transaction tx = client.transactions().withLabel("label2").txStart(OPTIMISTIC, READ_COMMITTED, 0, 0)) { + U.awaitQuiet(lockLatch); + + client.cache(DEFAULT_CACHE_NAME).putAll(generate(100, 10)); + + client.cache(DEFAULT_CACHE_NAME).put(0, 0); + + tx.commit(); + } + + break; + } + } + }, 4, "tx-thread"); + } }
