Logo Search packages:      
Sourcecode: zookeeper version File versions  Download package

void ZkFuseFile::childrenEventReceived ( const ZKWatcherEvent event  )  [inline]

Process a children event.

This method may:

  • Invalidate the children information cache.
  • Invoke ZooKeeper to update the children cache and register a new data watch so that the cache can be kept in-sync with the ZooKeeper node's children information.

Definition at line 2448 of file zkfuse.cc.

References _children, _childrenListener, _clearChildren(), _deleted, _getZkContext(), _hasChildrenListener, _initializedChildren, _isZombie(), _manager, _mutex, _path, _refCount, zk::ZooKeeperException::getZKErrorCode(), zk::ZooKeeperException::what(), and ZNONODE.

Referenced by ZkFuseHandleManager::eventReceived().

    {
        bool reclaim = false;
        int eventType = event.getType();
        int eventState = event.getState();

        LOG_DEBUG(LOG, "childrenEventReceived() path %s, type %d, state %d",
                  _path.c_str(), eventType, eventState);
        {
            AutoLock lock(_mutex);

            _hasChildrenListener = false;
            /* If zombie or disconnected, then invalidate cached children 
             * information. This clears _initializedChildren and eliminate 
             * the need to get the latest children information and
             * re-register children watch.
             */
            if (_initializedChildren && 
                (_isZombie() || eventState != ZOO_CONNECTED_STATE)) {
                LOG_DEBUG(LOG, "invalidate children");
                _clearChildren();
            }
            else if (_initializedChildren) {
                /* Keep cached children information so that we have some
                 * children information if get new children information
                 * fails. If there is failure, then on next open, 
                 * update() will attempt again to get children information
                 * again because _hasChildrenListener will be false.
                 *
                 * If children information cache is cleared here, then
                 * the following code to update children information cache
                 * and re-register children watch will not be executed
                 * and may result in the cached children information being
                 * out-of-sync with ZooKeeper.
                 *
                 * The children cache will be cleared if unable to 
                 * get children and re-establish watch.
                 */
                LOG_WARN(LOG, 
                         "%s children has changed while in-use, "
                         "type %d, state %d, refCount %d",
                         _path.c_str(), eventType, eventState, _refCount);
            }
            /* If children cache was valid and still connected, 
             * then get the latest children information from ZooKeeper 
             * and re-register children watch. This is required to 
             * keep the children information cache in-sync with ZooKeeper.
             */ 
            if (_initializedChildren && 
                eventState == ZOO_CONNECTED_STATE 
               ) {
                /* Should try to keep the cache in-sync, register call 
                 * callback again and get current children.
                 */ 
                try {
                    LOG_DEBUG(LOG, "update children");
                    NodeNames children;
                    _manager->getCommon().getZkAdapter()->
                      getNodeChildren(children, _path, 
                                      &_childrenListener, _getZkContext());
                    _hasChildrenListener = true;
                    LOG_DEBUG(LOG, "update children done");
                    _children.swap(children);
                    _deleted = false;
                } catch (const ZooKeeperException & e) {
                    if (e.getZKErrorCode() == ZNONODE) {
                        _deleted = true;
                        _clearChildren();
                    }
                    LOG_ERROR(LOG, "childrenEventReceived %s exception %s", 
                              _path.c_str(), e.what());
                    _children.clear();
                }
            }
        }
        LOG_DEBUG(LOG, "childrenEventReceived returns %d", reclaim);
    }


Generated by  Doxygen 1.6.0   Back to index