diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml index e79957d8c..cb4b52b73 100644 --- a/benchmarks/pom.xml +++ b/benchmarks/pom.xml @@ -6,7 +6,7 @@ com.aerospike aerospike-parent - 8.1.3 + 8.1.4 aerospike-benchmarks jar diff --git a/client/pom.xml b/client/pom.xml index 65008b3ef..dfe67163a 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -6,7 +6,7 @@ com.aerospike aerospike-parent - 8.1.3 + 8.1.4 aerospike-client-jdk8 jar diff --git a/client/src/com/aerospike/client/ResultCode.java b/client/src/com/aerospike/client/ResultCode.java index cdf1d8341..54a3ce096 100644 --- a/client/src/com/aerospike/client/ResultCode.java +++ b/client/src/com/aerospike/client/ResultCode.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 Aerospike, Inc. + * Copyright 2012-2024 Aerospike, Inc. * * Portions may be licensed to Aerospike, Inc. under one or more contributor * license agreements WHICH ARE COMPATIBLE WITH THE APACHE LICENSE, VERSION 2.0. @@ -233,6 +233,11 @@ public final class ResultCode { */ public static final int LOST_CONFLICT = 28; + /** + * Write can't complete until XDR finishes shipping. + */ + public static final int XDR_KEY_BUSY = 32; + /** * There are no more records left for query. */ @@ -582,6 +587,9 @@ public static String getResultString(int resultCode) { case LOST_CONFLICT: return "Transaction failed due to conflict with XDR"; + case XDR_KEY_BUSY: + return "Write can't complete until XDR finishes shipping"; + case QUERY_END: return "Query end"; diff --git a/client/src/com/aerospike/client/cluster/Cluster.java b/client/src/com/aerospike/client/cluster/Cluster.java index 7bb55ad3d..10e601a4c 100644 --- a/client/src/com/aerospike/client/cluster/Cluster.java +++ b/client/src/com/aerospike/client/cluster/Cluster.java @@ -569,11 +569,11 @@ private final void tend(boolean failIfNotConnected, boolean isInit) { } // Handle nodes changes determined from refreshes. - ArrayList removeList = findNodesToRemove(peers.refreshCount); + findNodesToRemove(peers); // Remove nodes in a batch. - if (removeList.size() > 0) { - removeNodes(removeList); + if (peers.removeList.size() > 0) { + removeNodes(peers.removeList); } } @@ -762,8 +762,9 @@ protected Node createNode(NodeValidator nv) { return node; } - private final ArrayList findNodesToRemove(int refreshCount) { - ArrayList removeList = new ArrayList(); + private final void findNodesToRemove(Peers peers) { + int refreshCount = peers.refreshCount; + ArrayList removeList = peers.removeList; for (Node node : nodes) { if (! node.isActive()) { @@ -797,7 +798,6 @@ private final ArrayList findNodesToRemove(int refreshCount) { } } } - return removeList; } private final boolean findNodeInPartitionMap(Node filter) { diff --git a/client/src/com/aerospike/client/cluster/Node.java b/client/src/com/aerospike/client/cluster/Node.java index e1d30a3f4..8fa6be5a7 100644 --- a/client/src/com/aerospike/client/cluster/Node.java +++ b/client/src/com/aerospike/client/cluster/Node.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 Aerospike, Inc. + * Copyright 2012-2024 Aerospike, Inc. * * Portions may be licensed to Aerospike, Inc. under one or more contributor * license agreements WHICH ARE COMPATIBLE WITH THE APACHE LICENSE, VERSION 2.0. @@ -426,7 +426,7 @@ protected final void refreshPeers(Peers peers) { boolean peersValidated = true; for (Peer peer : peers.peers) { - if (findPeerNode(cluster, peers, peer.nodeName)) { + if (findPeerNode(cluster, peers, peer)) { // Node already exists. Do not even try to connect to hosts. continue; } @@ -450,19 +450,16 @@ protected final void refreshPeers(Peers peers) { if (Log.warnEnabled()) { Log.warn("Peer node " + peer.nodeName + " is different than actual node " + nv.name + " for host " + host); } - - if (findPeerNode(cluster, peers, nv.name)) { - // Node already exists. Do not even try to connect to hosts. - nv.primaryConn.close(); - nodeValidated = true; - break; - } } // Create new node. Node node = cluster.createNode(nv); peers.nodes.put(nv.name, node); - nodeValidated = true; + nodeValidated = true; + + if (peer.replaceNode != null) { + peers.removeList.add(peer.replaceNode); + } break; } catch (Throwable e) { @@ -490,20 +487,37 @@ protected final void refreshPeers(Peers peers) { } } - private static boolean findPeerNode(Cluster cluster, Peers peers, String nodeName) { + private static boolean findPeerNode(Cluster cluster, Peers peers, Peer peer) { // Check global node map for existing cluster. - Node node = cluster.nodesMap.get(nodeName); + Node node = cluster.nodesMap.get(peer.nodeName); if (node != null) { - node.referenceCount++; - return true; + // Node name found. + if (node.failures <= 0 || node.address.getAddress().isLoopbackAddress()) { + // If the node does not have cluster tend errors or is localhost, + // reject new peer as the IP address does not need to change. + node.referenceCount++; + return true; + } + + // Match peer hosts with the node host. + for (Host h : peer.hosts) { + if (h.equals(node.host)) { + // Main node host is also the same as one of the peer hosts. + // Peer should not be added. + node.referenceCount++; + return true; + } + } + peer.replaceNode = node; } // Check local node map for this tend iteration. - node = peers.nodes.get(nodeName); + node = peers.nodes.get(peer.nodeName); if (node != null) { node.referenceCount++; + peer.replaceNode = null; return true; } return false; diff --git a/client/src/com/aerospike/client/cluster/Peer.java b/client/src/com/aerospike/client/cluster/Peer.java index 05ab16a1d..83712a5a8 100644 --- a/client/src/com/aerospike/client/cluster/Peer.java +++ b/client/src/com/aerospike/client/cluster/Peer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 Aerospike, Inc. + * Copyright 2012-2024 Aerospike, Inc. * * Portions may be licensed to Aerospike, Inc. under one or more contributor * license agreements WHICH ARE COMPATIBLE WITH THE APACHE LICENSE, VERSION 2.0. @@ -24,4 +24,5 @@ public final class Peer { String nodeName; String tlsName; List hosts; + Node replaceNode; } diff --git a/client/src/com/aerospike/client/cluster/Peers.java b/client/src/com/aerospike/client/cluster/Peers.java index bd28255d1..9c38f8a49 100644 --- a/client/src/com/aerospike/client/cluster/Peers.java +++ b/client/src/com/aerospike/client/cluster/Peers.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 Aerospike, Inc. + * Copyright 2012-2024 Aerospike, Inc. * * Portions may be licensed to Aerospike, Inc. under one or more contributor * license agreements WHICH ARE COMPATIBLE WITH THE APACHE LICENSE, VERSION 2.0. @@ -26,6 +26,7 @@ public final class Peers { public final ArrayList peers; public final HashMap nodes; + public final ArrayList removeList; private final HashSet invalidHosts; public int refreshCount; public boolean genChanged; @@ -33,6 +34,7 @@ public final class Peers { public Peers(int peerCapacity) { peers = new ArrayList(peerCapacity); nodes = new HashMap(16); + removeList = new ArrayList(); invalidHosts = new HashSet(8); } diff --git a/client/src/com/aerospike/client/command/RegisterCommand.java b/client/src/com/aerospike/client/command/RegisterCommand.java index b5b8b30c7..d55c7389b 100644 --- a/client/src/com/aerospike/client/command/RegisterCommand.java +++ b/client/src/com/aerospike/client/command/RegisterCommand.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 Aerospike, Inc. + * Copyright 2012-2024 Aerospike, Inc. * * Portions may be licensed to Aerospike, Inc. under one or more contributor * license agreements WHICH ARE COMPATIBLE WITH THE APACHE LICENSE, VERSION 2.0. @@ -55,11 +55,23 @@ public static RegisterTask register(Cluster cluster, Policy policy, byte[] bytes String file = null; String line = null; String message = null; + String messageNew = null; + int errorCode = 0; while (parser.next()) { String name = parser.getName(); - - if (name.equals("error")) { + + if (name.startsWith("ERROR")) { + // New error format: ERROR::;file=;line=;message= + int idx = name.indexOf(';'); + String s = (idx > 0)? name.substring(0, idx) : name; + Info.Error ie = new Info.Error(s); + messageNew = ie.message; + errorCode = ie.code; + file = parser.getValue(); + } + else if (name.equals("error")) { + // Old error format: error=;file=;line=;message= error = parser.getValue(); } else if (name.equals("file")) { @@ -72,8 +84,15 @@ else if (name.equals("message")) { message = parser.getStringBase64(); } } - - if (error != null) { + + if (errorCode != 0) { + throw new AerospikeException(errorCode, "Registration failed: " + System.lineSeparator() + + "File: " + file + System.lineSeparator() + + "Line: " + line + System.lineSeparator() + + "Message: " + messageNew + ". " + message + ); + } + else if (error != null) { throw new AerospikeException("Registration failed: " + error + System.lineSeparator() + "File: " + file + System.lineSeparator() + "Line: " + line + System.lineSeparator() + diff --git a/examples/pom.xml b/examples/pom.xml index 21ced4a1f..fad839b13 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -6,7 +6,7 @@ com.aerospike aerospike-parent - 8.1.3 + 8.1.4 aerospike-examples jar diff --git a/pom.xml b/pom.xml index 03d679aaf..359cdd7f7 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.aerospike aerospike-parent aerospike-parent - 8.1.3 + 8.1.4 pom https://github.com/aerospike/aerospike-client-java @@ -39,12 +39,12 @@ 2.18.1 3.2.0 - 4.1.111.Final + 4.1.112.Final 2.0.62.Final - 1.59.0 + 1.65.1 3.0.1 0.4 - 1.8.0 + 1.9.0 4.13.1 diff --git a/proxy/pom.xml b/proxy/pom.xml index 8e8ebd270..9be7dce26 100644 --- a/proxy/pom.xml +++ b/proxy/pom.xml @@ -6,7 +6,7 @@ com.aerospike aerospike-parent - 8.1.3 + 8.1.4 aerospike-proxy-client jar diff --git a/test/pom.xml b/test/pom.xml index ac86ff071..1ed1b89a9 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -6,7 +6,7 @@ com.aerospike aerospike-parent - 8.1.3 + 8.1.4 aerospike-client-test jar