You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@helix.apache.org by xy...@apache.org on 2023/03/14 18:40:41 UTC
[helix] branch metaclient updated: TTL Node Lattice Implementation (#2401)
This is an automated email from the ASF dual-hosted git repository.
xyuanlu pushed a commit to branch metaclient
in repository https://gitbox.apache.org/repos/asf/helix.git
The following commit(s) were added to refs/heads/metaclient by this push:
new 8151b2ffd TTL Node Lattice Implementation (#2401)
8151b2ffd is described below
commit 8151b2ffde27db8f84108691d30666a2fb8b7b5e
Author: Marcos Rico Peng <55...@users.noreply.github.com>
AuthorDate: Tue Mar 14 14:40:34 2023 -0400
TTL Node Lattice Implementation (#2401)
TTL Node Lattice Implementation
---
.../helix/metaclient/api/MetaClientInterface.java | 3 +-
.../helix/metaclient/impl/zk/ZkMetaClient.java | 16 ++++++--
.../metaclient/impl/zk/util/ZkMetaClientUtil.java | 9 ++---
.../helix/metaclient/impl/zk/TestZkMetaClient.java | 47 ++++++++++++++++++----
.../metaclient/impl/zk/ZkMetaClientTestBase.java | 2 +
5 files changed, 60 insertions(+), 17 deletions(-)
diff --git a/meta-client/src/main/java/org/apache/helix/metaclient/api/MetaClientInterface.java b/meta-client/src/main/java/org/apache/helix/metaclient/api/MetaClientInterface.java
index 7445a0d33..375c0814c 100644
--- a/meta-client/src/main/java/org/apache/helix/metaclient/api/MetaClientInterface.java
+++ b/meta-client/src/main/java/org/apache/helix/metaclient/api/MetaClientInterface.java
@@ -82,6 +82,7 @@ public interface MetaClientInterface<T> {
/**
* Interface representing the metadata of an entry. It contains entry type and version number.
* TODO: we will add session ID to entry stats in the future
+ * TODO: Add support for expiry time
*/
class Stat {
private final int _version;
@@ -202,7 +203,7 @@ public interface MetaClientInterface<T> {
/**
* API for transaction. The list of operation will be executed as an atomic operation.
- * @param ops a list of operations. These operations will all be executed or non of them.
+ * @param ops a list of operations. These operations will all be executed or none of them.
* @return Return a list of OpResult.
*/
List<OpResult> transactionOP(final Iterable<Op> ops);
diff --git a/meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/ZkMetaClient.java b/meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/ZkMetaClient.java
index d3542e1fa..2a9262208 100644
--- a/meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/ZkMetaClient.java
+++ b/meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/ZkMetaClient.java
@@ -34,6 +34,7 @@ import org.apache.helix.metaclient.api.MetaClientInterface;
import org.apache.helix.metaclient.api.Op;
import org.apache.helix.metaclient.api.OpResult;
import org.apache.helix.metaclient.exception.MetaClientException;
+import org.apache.helix.metaclient.exception.MetaClientNoNodeException;
import org.apache.helix.metaclient.impl.zk.adapter.DataListenerAdapter;
import org.apache.helix.metaclient.impl.zk.adapter.DirectChildListenerAdapter;
import org.apache.helix.metaclient.impl.zk.adapter.StateChangeListenerAdapter;
@@ -94,12 +95,20 @@ public class ZkMetaClient<T> implements MetaClientInterface<T>, AutoCloseable {
@Override
public void createWithTTL(String key, T data, long ttl) {
- throw new UnsupportedOperationException("TTL nodes aren't yet supported.");
+ try{
+ _zkClient.createPersistentWithTTL(key, data, ttl);
+ } catch (ZkException e) {
+ throw translateZkExceptionToMetaclientException(e);
+ }
}
@Override
public void renewTTLNode(String key) {
- throw new UnsupportedOperationException("TTL nodes aren't yet supported.");
+ T oldData = get(key);
+ if (oldData == null) {
+ throw new MetaClientNoNodeException("Node at " + key + " does not exist.");
+ }
+ set(key, oldData, _zkClient.getStat(key).getVersion());
}
@Override
@@ -125,6 +134,7 @@ public class ZkMetaClient<T> implements MetaClientInterface<T>, AutoCloseable {
}
}
+ //TODO: Get Expiry Time in Stat
@Override
public Stat exists(String key) {
org.apache.zookeeper.data.Stat zkStats;
@@ -134,7 +144,7 @@ public class ZkMetaClient<T> implements MetaClientInterface<T>, AutoCloseable {
return null;
}
return new Stat(convertZkEntryModeToMetaClientEntryMode(zkStats.getEphemeralOwner()),
- zkStats.getVersion());
+ zkStats.getVersion(), zkStats.getCtime(), zkStats.getMtime(), -1);
} catch (ZkException e) {
throw translateZkExceptionToMetaclientException(e);
}
diff --git a/meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/util/ZkMetaClientUtil.java b/meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/util/ZkMetaClientUtil.java
index a9bee4cbb..f21a883f3 100644
--- a/meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/util/ZkMetaClientUtil.java
+++ b/meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/util/ZkMetaClientUtil.java
@@ -37,7 +37,7 @@ import org.apache.helix.metaclient.exception.MetaClientTimeoutException;
import org.apache.helix.zookeeper.zkclient.exception.ZkBadVersionException;
import org.apache.helix.zookeeper.zkclient.exception.ZkException;
import org.apache.helix.zookeeper.zkclient.exception.ZkInterruptedException;
-import org.apache.helix.zookeeper.zkclient.exception.ZkNodeExistsException;
+import org.apache.helix.zookeeper.zkclient.exception.ZkNoNodeException;
import org.apache.helix.zookeeper.zkclient.exception.ZkTimeoutException;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
@@ -219,16 +219,15 @@ public class ZkMetaClientUtil {
return MetaClientInterface.EntryMode.CONTAINER;
case NORMAL:
return MetaClientInterface.EntryMode.EPHEMERAL;
- // TODO: TTL is not supported now.
- //case TTL:
- // return EntryMode.TTL;
+ case TTL:
+ return MetaClientInterface.EntryMode.TTL;
default:
throw new IllegalArgumentException(zkEphemeralType + " is not supported.");
}
}
public static MetaClientException translateZkExceptionToMetaclientException(ZkException e) {
- if (e instanceof ZkNodeExistsException) {
+ if (e instanceof ZkNoNodeException) {
return new MetaClientNoNodeException(e);
} else if (e instanceof ZkBadVersionException) {
return new MetaClientBadVersionException(e);
diff --git a/meta-client/src/test/java/org/apache/helix/metaclient/impl/zk/TestZkMetaClient.java b/meta-client/src/test/java/org/apache/helix/metaclient/impl/zk/TestZkMetaClient.java
index 49cbae1f3..cdb894b34 100644
--- a/meta-client/src/test/java/org/apache/helix/metaclient/impl/zk/TestZkMetaClient.java
+++ b/meta-client/src/test/java/org/apache/helix/metaclient/impl/zk/TestZkMetaClient.java
@@ -19,12 +19,17 @@ package org.apache.helix.metaclient.impl.zk;
* under the License.
*/
+import org.apache.helix.metaclient.api.DataUpdater;
+import org.apache.helix.metaclient.api.MetaClientInterface;
+import org.apache.helix.metaclient.exception.MetaClientException;
+import org.apache.helix.metaclient.api.DirectChildChangeListener;
+
import java.util.Arrays;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
+import java.util.Map;
+import java.util.HashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -33,12 +38,9 @@ import java.util.concurrent.atomic.AtomicInteger;
import org.apache.commons.lang3.NotImplementedException;
import org.apache.helix.metaclient.api.ConnectStateChangeListener;
import org.apache.helix.metaclient.api.DataChangeListener;
-import org.apache.helix.metaclient.api.DataUpdater;
-import org.apache.helix.metaclient.api.DirectChildChangeListener;
-import org.apache.helix.metaclient.api.MetaClientInterface;
import org.apache.helix.metaclient.api.Op;
import org.apache.helix.metaclient.api.OpResult;
-import org.apache.helix.metaclient.exception.MetaClientException;
+import org.apache.helix.metaclient.exception.MetaClientNoNodeException;
import org.apache.helix.metaclient.impl.zk.factory.ZkMetaClientConfig;
import org.apache.zookeeper.KeeperException;
import org.testng.Assert;
@@ -53,8 +55,8 @@ public class TestZkMetaClient extends ZkMetaClientTestBase{
private static final String ZK_ADDR = "localhost:2183";
private static final int DEFAULT_TIMEOUT_MS = 1000;
private static final String ENTRY_STRING_VALUE = "test-value";
- private static String TRANSACTION_TEST_PARENT_PATH = "/transactionOpTestPath";
- private static final String TEST_INVALID_PATH = "_invalid/a/b/c";
+ private static final String TRANSACTION_TEST_PARENT_PATH = "/transactionOpTestPath";
+ private static final String TEST_INVALID_PATH = "/_invalid/a/b/c";
private final Object _syncObject = new Object();
@@ -84,6 +86,35 @@ public class TestZkMetaClient extends ZkMetaClientTestBase{
}
}
+ @Test
+ public void testCreateTTL() {
+ final String key = "/TestZkMetaClient_testTTL";
+ try (ZkMetaClient<String> zkMetaClient = createZkMetaClient()) {
+ zkMetaClient.connect();
+ zkMetaClient.createWithTTL(key, ENTRY_STRING_VALUE, 1000);
+ Assert.assertNotNull(zkMetaClient.exists(key));
+ }
+ }
+
+ @Test
+ public void testRenewTTL() {
+ final String key = "/TestZkMetaClient_testRenewTTL_1";
+ try (ZkMetaClient<String> zkMetaClient = createZkMetaClient()) {
+ zkMetaClient.connect();
+ zkMetaClient.createWithTTL(key, ENTRY_STRING_VALUE, 10000);
+ Assert.assertNotNull(zkMetaClient.exists(key));
+ MetaClientInterface.Stat stat = zkMetaClient.exists(key);
+ zkMetaClient.renewTTLNode(key);
+ // Renewing a ttl node changes the nodes modified_time. Should be different
+ // from the time the node was created.
+ Assert.assertNotSame(stat.getCreationTime(), stat.getModifiedTime());
+ try {
+ zkMetaClient.renewTTLNode(TEST_INVALID_PATH);
+ } catch (MetaClientNoNodeException ignored) {
+ }
+ }
+ }
+
@Test
public void testGet() {
final String key = "/TestZkMetaClient_testGet";
diff --git a/meta-client/src/test/java/org/apache/helix/metaclient/impl/zk/ZkMetaClientTestBase.java b/meta-client/src/test/java/org/apache/helix/metaclient/impl/zk/ZkMetaClientTestBase.java
index cbc9832e1..51c655602 100644
--- a/meta-client/src/test/java/org/apache/helix/metaclient/impl/zk/ZkMetaClientTestBase.java
+++ b/meta-client/src/test/java/org/apache/helix/metaclient/impl/zk/ZkMetaClientTestBase.java
@@ -49,6 +49,8 @@ public abstract class ZkMetaClientTestBase {
*/
@BeforeSuite
public void prepare() {
+ // Enable extended types and create a ZkClient
+ System.setProperty("zookeeper.extendedTypesEnabled", "true");
// start local zookeeper server
_zkServer = startZkServer(ZK_ADDR);
}