【问题标题】:When using curator treeCache, how can I ensure cache is ready?使用 curator treeCache 时,如何确保缓存已准备就绪?
【发布时间】:2018-03-23 18:43:18
【问题描述】:

使用curatortreeCache时,如何确保缓存已准备好?

cache.start()之后,如果我立即调用getCurrentData,它会返回null,那么如何确保缓存已经准备好呢?谁能给我一个例子?谢谢

client = CuratorFrameworkFactory.builder()
             .connectString(connectionString)
             .retryPolicy(new ExponentialBackoffRetry(zkConnectionTimeoutMs, 3))
             .sessionTimeoutMs(zkSessionTimeoutMs)
             .build();
client.start();

cache = new TreeCache(client, rootPath);
cache.start();
ChildData child = cache.getCurrentData(rootPath); // child is null
Thread.sleep(50);   // must sleep for a while
child = cache.getCurrentData(rootPath); // child is ok

【问题讨论】:

    标签: java apache-zookeeper apache-curator


    【解决方案1】:

    您可以为 Treecache 添加一个侦听器并侦听 INITIALIZED 事件。

        Semaphore sem = new Semaphore(0);
        client = CuratorFrameworkFactory.builder()
                                     .connectString(connectionString)
                                     .retryPolicy(new ExponentialBackoffRetry(zkConnectionTimeoutMs, 3))
                                     .sessionTimeoutMs(zkSessionTimeoutMs)
                                     .build();
            client.start();
    
            cache = new TreeCache(client, rootPath);
                        cache.start();
    
            TreeCacheListener listener = new TreeCacheListener() {
    
                                        @Override
                                        public void childEvent(CuratorFramework client, TreeCacheEvent event)
                                                throws Exception {
                                            switch (event.getType()) {
                                            case INITIALIZED: {
    
                                              sem.release();
    
                                            }
    
                                        }
    
                                    };
            cache.getListenable().addListener(listener);
           sem.acquire();
    child = cache.getCurrentData(rootPath);
    

    【讨论】:

    • 有人找到比这更好的解决方案吗?
    【解决方案2】:

    来自getCurrentChildren的代码

     public Map<String, ChildData> getCurrentChildren(String fullPath)
    {
        TreeNode node = find(fullPath);
        if ( node == null || node.nodeState.get() != NodeState.LIVE )
        {
            return null;
        }
        ConcurrentMap<String, TreeNode> map = node.children.get();
        Map<String, ChildData> result;
        if ( map == null )
        {
            result = ImmutableMap.of();
        }
        else
        {
            ImmutableMap.Builder<String, ChildData> builder = ImmutableMap.builder();
            for ( Map.Entry<String, TreeNode> entry : map.entrySet() )
            {
                TreeNode childNode = entry.getValue();
                ChildData childData = new ChildData(childNode.path, childNode.stat.get(), childNode.data.get());
                // Double-check liveness after retreiving data.
                if ( childNode.nodeState.get() == NodeState.LIVE )
                {
                    builder.put(entry.getKey(), childData);
                }
            }
            result = builder.build();
        }
    
        // Double-check liveness after retreiving children.
        return node.nodeState.get() == NodeState.LIVE ? result : null;
    }
    

    可以看到,当 NodeState 为 PENDING 或 DEAD 或不存在时,它会返回 null,当 NodeState 为 LIVE 时,它会返回一个 Map 实例。所以当返回值不为空时,缓存就准备好了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-15
      相关资源
      最近更新 更多