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/10/05 21:47:31 UTC
[helix] 01/04: MetaClientCache Part 1 - API's, configs, and builders (#2612)
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
commit a6252856b14c8e7164cd4d70da2ebfd72218472b
Author: Marcos Rico Peng <55...@users.noreply.github.com>
AuthorDate: Tue Sep 12 22:24:22 2023 +0200
MetaClientCache Part 1 - API's, configs, and builders (#2612)
MetaClientCache Part 1 - API's, configs, and builders
---------
Co-authored-by: mapeng <ma...@linkedin.com>
---
.../metaclient/api/MetaClientCacheInterface.java | 61 ++++++++++++++
.../MetaClientCacheConfig.java} | 43 ++++++----
.../metaclient/factories/MetaClientFactory.java | 17 ++++
.../metaclient/impl/zk/ZkMetaClientCache.java | 94 ++++++++++++++++++++++
.../impl/zk/factory/ZkMetaClientFactory.java | 15 ++++
.../metaclient/impl/zk/TestZkMetaClientCache.java | 57 +++++++++++++
6 files changed, 272 insertions(+), 15 deletions(-)
diff --git a/meta-client/src/main/java/org/apache/helix/metaclient/api/MetaClientCacheInterface.java b/meta-client/src/main/java/org/apache/helix/metaclient/api/MetaClientCacheInterface.java
new file mode 100644
index 000000000..348bd0929
--- /dev/null
+++ b/meta-client/src/main/java/org/apache/helix/metaclient/api/MetaClientCacheInterface.java
@@ -0,0 +1,61 @@
+package org.apache.helix.metaclient.api;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.HashMap;
+import java.util.Map;
+
+public interface MetaClientCacheInterface<T> extends MetaClientInterface<T> {
+
+ /**
+ * TrieNode class to store the children of the entries to be cached.
+ */
+ class TrieNode {
+ // A mapping between trie key and children nodes.
+ private Map<String, TrieNode> _children;
+
+ // the complete path/prefix leading to the current node.
+ private final String _path;
+
+ private final String _nodeKey;
+
+ TrieNode(String path, String nodeKey) {
+ _path = path;
+ _nodeKey = nodeKey;
+ _children = new HashMap<>();
+ }
+
+ public Map<String, TrieNode> getChildren() {
+ return _children;
+ }
+
+ public String getPath() {
+ return _path;
+ }
+
+ public String getNodeKey() {
+ return _nodeKey;
+ }
+
+ public void addChild(String key, TrieNode node) {
+ _children.put(key, node);
+ }
+ }
+}
diff --git a/meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/factory/ZkMetaClientFactory.java b/meta-client/src/main/java/org/apache/helix/metaclient/factories/MetaClientCacheConfig.java
similarity index 50%
copy from meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/factory/ZkMetaClientFactory.java
copy to meta-client/src/main/java/org/apache/helix/metaclient/factories/MetaClientCacheConfig.java
index 9eba28b91..9e0323601 100644
--- a/meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/factory/ZkMetaClientFactory.java
+++ b/meta-client/src/main/java/org/apache/helix/metaclient/factories/MetaClientCacheConfig.java
@@ -1,4 +1,4 @@
-package org.apache.helix.metaclient.impl.zk.factory;
+package org.apache.helix.metaclient.factories;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@@ -19,21 +19,34 @@ package org.apache.helix.metaclient.impl.zk.factory;
* under the License.
*/
-import org.apache.helix.metaclient.api.MetaClientInterface;
-import org.apache.helix.metaclient.factories.MetaClientConfig;
-import org.apache.helix.metaclient.factories.MetaClientFactory;
-import org.apache.helix.metaclient.impl.zk.ZkMetaClient;
-public class ZkMetaClientFactory extends MetaClientFactory {
- @Override
- public MetaClientInterface getMetaClient(MetaClientConfig config) {
- if (config == null) {
- throw new IllegalArgumentException("MetaClientConfig cannot be null.");
+
+public class MetaClientCacheConfig {
+ private final String _rootEntry;
+ private boolean _cacheData = false;
+ private boolean _cacheChildren = false;
+ private boolean _lazyCaching = true;
+
+ public MetaClientCacheConfig(String rootEntry, boolean cacheData, boolean cacheChildren, boolean lazyCaching) {
+ _rootEntry = rootEntry;
+ _cacheData = cacheData;
+ _cacheChildren = cacheChildren;
+ _lazyCaching = lazyCaching;
}
- if (MetaClientConfig.StoreType.ZOOKEEPER.equals(config.getStoreType())
- && config instanceof ZkMetaClientConfig) {
- return new ZkMetaClient((ZkMetaClientConfig) config);
+
+ public String getRootEntry() {
+ return _rootEntry;
+ }
+
+ public boolean getCacheData() {
+ return _cacheData;
+ }
+
+ public boolean getCacheChildren() {
+ return _cacheChildren;
+ }
+
+ public boolean getLazyCaching() {
+ return _lazyCaching;
}
- throw new IllegalArgumentException("Invalid MetaClientConfig type.");
- }
}
diff --git a/meta-client/src/main/java/org/apache/helix/metaclient/factories/MetaClientFactory.java b/meta-client/src/main/java/org/apache/helix/metaclient/factories/MetaClientFactory.java
index 045374332..ebb4549da 100644
--- a/meta-client/src/main/java/org/apache/helix/metaclient/factories/MetaClientFactory.java
+++ b/meta-client/src/main/java/org/apache/helix/metaclient/factories/MetaClientFactory.java
@@ -20,6 +20,7 @@ package org.apache.helix.metaclient.factories;
*/
+import org.apache.helix.metaclient.api.MetaClientCacheInterface;
import org.apache.helix.metaclient.api.MetaClientInterface;
import org.apache.helix.metaclient.impl.zk.factory.ZkMetaClientConfig;
import org.apache.helix.metaclient.impl.zk.factory.ZkMetaClientFactory;
@@ -49,4 +50,20 @@ public class MetaClientFactory {
}
return null;
}
+
+ public MetaClientCacheInterface getMetaClientCache(MetaClientConfig config, MetaClientCacheConfig cacheConfig) {
+ if (config == null) {
+ throw new IllegalArgumentException("MetaClientConfig cannot be null.");
+ }
+ if (MetaClientConfig.StoreType.ZOOKEEPER.equals(config.getStoreType())) {
+ ZkMetaClientConfig zkMetaClientConfig = new ZkMetaClientConfig.ZkMetaClientConfigBuilder().
+ setConnectionAddress(config.getConnectionAddress())
+ .setMetaClientReconnectPolicy(config.getMetaClientReconnectPolicy())
+ .setConnectionInitTimeoutInMillis(config.getConnectionInitTimeoutInMillis())
+ .setSessionTimeoutInMillis(config.getSessionTimeoutInMillis())
+ .build();
+ return new ZkMetaClientFactory().getMetaClientCache(zkMetaClientConfig, cacheConfig);
+ }
+ return null;
+ }
}
diff --git a/meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/ZkMetaClientCache.java b/meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/ZkMetaClientCache.java
new file mode 100644
index 000000000..af1c9d791
--- /dev/null
+++ b/meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/ZkMetaClientCache.java
@@ -0,0 +1,94 @@
+package org.apache.helix.metaclient.impl.zk;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.helix.metaclient.api.ChildChangeListener;
+import org.apache.helix.metaclient.api.MetaClientCacheInterface;
+import org.apache.helix.metaclient.datamodel.DataRecord;
+import org.apache.helix.metaclient.exception.MetaClientException;
+import org.apache.helix.metaclient.factories.MetaClientCacheConfig;
+import org.apache.helix.metaclient.factories.MetaClientConfig;
+import org.apache.helix.metaclient.impl.zk.factory.ZkMetaClientConfig;
+import org.apache.helix.metaclient.impl.zk.factory.ZkMetaClientFactory;
+import org.apache.helix.metaclient.recipes.lock.LockInfoSerializer;
+import org.apache.helix.zookeeper.zkclient.ZkClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.Map;
+
+public class ZkMetaClientCache<T> extends ZkMetaClient<T> implements MetaClientCacheInterface<T> {
+
+ private Map<String, DataRecord> _dataCacheMap;
+ private final String _rootEntry;
+ private TrieNode _childrenCacheTree;
+ private ChildChangeListener _eventListener;
+ private boolean _cacheData;
+ private boolean _cacheChildren;
+ private boolean _lazyCaching;
+ private static final Logger LOG = LoggerFactory.getLogger(ZkMetaClientCache.class);
+ private ZkClient _cacheClient;
+
+ /**
+ * Constructor for ZkMetaClientCache.
+ * @param config ZkMetaClientConfig
+ * @param cacheConfig MetaClientCacheConfig
+ */
+ public ZkMetaClientCache(ZkMetaClientConfig config, MetaClientCacheConfig cacheConfig) {
+ super(config);
+ _cacheClient = getZkClient();
+ _rootEntry = cacheConfig.getRootEntry();
+ _lazyCaching = cacheConfig.getLazyCaching();
+ _cacheData = cacheConfig.getCacheData();
+ _cacheChildren = cacheConfig.getCacheChildren();
+ }
+
+ @Override
+ public Stat exists(String key) {
+ throw new MetaClientException("Not implemented yet.");
+ }
+
+ @Override
+ public T get(final String key) {
+ throw new MetaClientException("Not implemented yet.");
+ }
+
+ @Override
+ public List<String> getDirectChildrenKeys(final String key) {
+ throw new MetaClientException("Not implemented yet.");
+ }
+
+ @Override
+ public int countDirectChildren(final String key) {
+ throw new MetaClientException("Not implemented yet.");
+ }
+
+ @Override
+ public List<T> get(List<String> keys) {
+ throw new MetaClientException("Not implemented yet.");
+ }
+
+ @Override
+ public List<Stat> exists(List<String> keys) {
+ throw new MetaClientException("Not implemented yet.");
+ }
+
+}
diff --git a/meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/factory/ZkMetaClientFactory.java b/meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/factory/ZkMetaClientFactory.java
index 9eba28b91..c4018eb2f 100644
--- a/meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/factory/ZkMetaClientFactory.java
+++ b/meta-client/src/main/java/org/apache/helix/metaclient/impl/zk/factory/ZkMetaClientFactory.java
@@ -19,10 +19,13 @@ package org.apache.helix.metaclient.impl.zk.factory;
* under the License.
*/
+import org.apache.helix.metaclient.api.MetaClientCacheInterface;
import org.apache.helix.metaclient.api.MetaClientInterface;
+import org.apache.helix.metaclient.factories.MetaClientCacheConfig;
import org.apache.helix.metaclient.factories.MetaClientConfig;
import org.apache.helix.metaclient.factories.MetaClientFactory;
import org.apache.helix.metaclient.impl.zk.ZkMetaClient;
+import org.apache.helix.metaclient.impl.zk.ZkMetaClientCache;
public class ZkMetaClientFactory extends MetaClientFactory {
@Override
@@ -36,4 +39,16 @@ public class ZkMetaClientFactory extends MetaClientFactory {
}
throw new IllegalArgumentException("Invalid MetaClientConfig type.");
}
+
+ @Override
+ public MetaClientCacheInterface getMetaClientCache(MetaClientConfig config, MetaClientCacheConfig cacheConfig) {
+ if (config == null) {
+ throw new IllegalArgumentException("MetaClientConfig cannot be null.");
+ }
+ if (MetaClientConfig.StoreType.ZOOKEEPER.equals(config.getStoreType())
+ && config instanceof ZkMetaClientConfig) {
+ return new ZkMetaClientCache((ZkMetaClientConfig) config, cacheConfig);
+ }
+ throw new IllegalArgumentException("Invalid MetaClientConfig type.");
+ }
}
diff --git a/meta-client/src/test/java/org/apache/helix/metaclient/impl/zk/TestZkMetaClientCache.java b/meta-client/src/test/java/org/apache/helix/metaclient/impl/zk/TestZkMetaClientCache.java
new file mode 100644
index 000000000..a3a5b4eee
--- /dev/null
+++ b/meta-client/src/test/java/org/apache/helix/metaclient/impl/zk/TestZkMetaClientCache.java
@@ -0,0 +1,57 @@
+package org.apache.helix.metaclient.impl.zk;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+import org.apache.helix.metaclient.factories.MetaClientCacheConfig;
+import org.apache.helix.metaclient.impl.zk.factory.ZkMetaClientConfig;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class TestZkMetaClientCache extends ZkMetaClientTestBase {
+ private static final String PATH = "/Cache";
+
+ @Test
+ public void testCreateClient() {
+ final String key = "/TestZkMetaClientCache_testCreate";
+ try (ZkMetaClient<String> zkMetaClientCache = createZkMetaClientCache()) {
+ zkMetaClientCache.connect();
+ // Perform some random non-read operation
+ zkMetaClientCache.create(key, ENTRY_STRING_VALUE);
+
+ try {
+ //Perform some read operation - should fail.
+ // TODO: Remove this once implemented.
+ zkMetaClientCache.get(key);
+ Assert.fail("Should have failed with non implemented yet.");
+ } catch (Exception ignored) {
+ }
+ }
+ }
+
+ protected static ZkMetaClientCache<String> createZkMetaClientCache() {
+ ZkMetaClientConfig config =
+ new ZkMetaClientConfig.ZkMetaClientConfigBuilder().setConnectionAddress(ZK_ADDR)
+ //.setZkSerializer(new TestStringSerializer())
+ .build();
+ MetaClientCacheConfig cacheConfig = new MetaClientCacheConfig(PATH, true, true, true);
+ return new ZkMetaClientCache<>(config, cacheConfig);
+ }
+}