【Curator NodeCache 源码解析】

NodeCache

  1. NodeCache在new对象时候会调用client.newWatcherRemoveCuratorFramework去新建一个监听客户端。
  /**
     * @param client curztor client
     * @param path the full path to the node to cache
     * @param dataIsCompressed if true, data in the path is compressed
     */
    public NodeCache(CuratorFramework client, String path, boolean dataIsCompressed)
    {
        this.client = client.newWatcherRemoveCuratorFramework();
        this.path = PathUtils.validatePath(path);
        this.dataIsCompressed = dataIsCompressed;
    }

  1. start() 启动缓存服务
 public void     start(boolean buildInitial) throws Exception
    {
      //设值启动状态
       Preconditions.checkState(state.compareAndSet(State.LATENT,              State.STARTED), "Cannot be started more than once");

      //增加连接状态监听 client.getConnectionStateListenable().addListener(connectionStateListener);
    // 进行初始化操作
        if ( buildInitial )
        {
            client.checkExists().creatingParentContainersIfNeeded().forPath(path);
            internalRebuild();
        }
        reset();
    }
    // 判断是否是启动连接状态,判断节点是否存在
   private void     reset() throws Exception
    {
        if ( (state.get() == State.STARTED) && isConnected.get() )
        {
            client.checkExists().creatingParentContainersIfNeeded().usingWatcher(watcher).inBackground(backgroundCallback).forPath(path);
        }
    }

在reset()方法中传入了两个对象,一个监听对象watcher,一个是回调对象backgroundCallback(异步回调)
刚开始启动会注册一个watcher对象,当服务器返回数据回来时候会调用回调函数

  private void processBackgroundResult(CuratorEvent event) throws Exception
    {
        // 当发生获取数据或者是判断节点是否存在时候进行监听
        switch ( event.getType() )
        {
            case GET_DATA:
                 // 响应状态为ok时,将刷新本地缓存的数据
                if ( event.getResultCode() == KeeperException.Code.OK.intValue() )
                {   // 获取监听到的数据变动集合
                    ChildData childData = new ChildData(path, event.getStat(), event.getData());
                    // 刷新本地缓存数据
                    setNewData(childData);
                }
                break;
            }

            case EXISTS:
            {
                if ( event.getResultCode() == KeeperException.Code.NONODE.intValue() )
                {
                    setNewData(null);
                }
                else if ( event.getResultCode() == KeeperException.Code.OK.intValue() )
                {
                    if ( dataIsCompressed )
                    {
                        client.getData().decompressed().usingWatcher(watcher).inBackground(backgroundCallback).forPath(path);
                    }
                    else
                    {
                        client.getData().usingWatcher(watcher).inBackground(backgroundCallback).forPath(path);
                    }
                }
                break;
            }
        }

刷新本地缓存数据,触发监听

   //private final ListenerContainer<NodeCacheListener> listeners 监听容器集合
  private void setNewData(ChildData newData) throws InterruptedException
    {   
        // data 缓存对象,getAndSet 设置新值并返回旧值
        ChildData   previousData = data.getAndSet(newData);
        // 两个对象不一致时,触发监听
        if ( !Objects.equal(previousData, newData) )
        {
            // 将本地的监听容器循环
            listeners.forEach
            (   // 将监听对象作为参数传入给foreach方法,之后方法里会调用
                new Function<NodeCacheListener, Void>()
                {
                    @Override
                    public Void apply(NodeCacheListener listener)
                    {
                        try
                        {
                            listener.nodeChanged();
                        }
                        catch ( Exception e )
                        {
                            ThreadUtils.checkInterrupted(e);
                            log.error("Calling listener", e);
                        }
                        return null;
                    }
                }
            );

            if ( rebuildTestExchanger != null )
            {
                try
                {
                    rebuildTestExchanger.exchange(new Object());
                }
                catch ( InterruptedException e )
                {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }
    

 //接口方法Function<F,T> F是参数 T是返回值
@GwtCompatible
public interface Function<F, T> {
    @Nullable
    @CanIgnoreReturnValue
    T apply(@Nullable F var1);

    boolean equals(@Nullable Object var1);
}
    // ListenerContainer 监听容器里foreach方法,循环调用每一个监听器
  /**
     * Utility - apply the given function to each listener. The function receives
     * the listener as an argument.
     *
     * @param function function to call for each listener
     */
    public void     forEach(final Function<T, Void> function)
    {
        for ( final ListenerEntry<T> entry : listeners.values() )
        {
            entry.executor.execute
            (
                new Runnable()
                {
                    @Override
                    public void run()
                    {
                        try
                        {
                            function.apply(entry.listener);
                        }
                        catch ( Throwable e )
                        {
                            ThreadUtils.checkInterrupted(e);
                            log.error(String.format("Listener (%s) threw an exception", entry.listener), e);
                        }
                    }
                }
            );
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值