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

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

Process a data event.

This method may:

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

This method does not change the active data. Active data will be changed to a later version by update() at the appropriate time.

See also:
update.

Definition at line 2350 of file zkfuse.cc.

References _clearChildren(), _clearData(), _dataListener, _deleted, _getZkContext(), _hasDataListener, _initializedData, _isZombie(), _latestData, _latestStat, _manager, _mutex, _openDirCount, _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();

        /*
          IMPORTANT: 
          
          Do not mark ZkFuseFile instance as deleted when a ZOO_DELETED_EVENT 
          is received without checking with ZooKeeper. An example of 
          problematic sequence would be:

          1. Create node.
          2. Set data and watch.
          3. Delete node.
          4. Create node.
          5. Deleted event received.

          It is a bug to mark the ZkFuseFile instance as deleted after 
          step 5 because the node exists.
          
          Therefore, this method should always contact ZooKeeper to keep the
          data cache (and deleted status) up-to-date if necessary.
         */
        LOG_DEBUG(LOG, "dataEventReceived() path %s, type %d, state %d",
                  _path.c_str(), eventType, eventState);
        {
            AutoLock lock(_mutex);

            _hasDataListener = false;
            /* If zombie, then invalidate cached data.
             * This clears _initializedData and eliminate 
             * the need to get the latest data from ZooKeeper and
             * re-register data watch. 
             */
            if (_isZombie() && _initializedData) {
                LOG_DEBUG(LOG, "invalidate data");
                _clearData();
            }
            else if ((_refCount - _openDirCount) > 0) {
                /* Don't invalidate cached data because clients of currently
                 * open files don't expect the data to change from under them.
                 * If data acted upon by these clients have become stale,
                 * then the clients will get an error when ZkFuse attempts to
                 * flush dirty data. The clients will not get error 
                 * notification if they don't modify the stale data.
                 *
                 * If data cache is cleared here, then the following code 
                 * to update data cache and re-register data watch will not 
                 * be executed and may result in the cached data being
                 * out-of-sync with ZooKeeper.
                 */
                LOG_WARN(LOG, 
                         "%s data has changed while in-use, "
                         "type %d, state %d, refCount %d",
                         _path.c_str(), eventType, eventState, _refCount);
            }
            /* If cache was valid and still connected
             * then get the latest data from ZooKeeper 
             * and re-register data watch. This is required to keep 
             * the data cache in-sync with ZooKeeper.
             */ 
            if (_initializedData && 
                eventState == ZOO_CONNECTED_STATE 
               ) {
                try {
                    LOG_DEBUG(LOG, "register data watcher");
                    _latestData = 
                        _manager->getCommon().getZkAdapter()->
                        getNodeData(_path, &_dataListener, _getZkContext(), 
                                    &_latestStat);
                    _hasDataListener = true;
                    LOG_DEBUG(LOG, 
                              "get data done, version %u, cversion %u done",
                              _latestStat.version, _latestStat.cversion);
                    _deleted = false;
                } catch (const ZooKeeperException & e) {
                    if (e.getZKErrorCode() == ZNONODE) {
                        _deleted = true;
                        _clearChildren();
                    }
                    LOG_ERROR(LOG, "dataEventReceived %s exception %s", 
                              _path.c_str(), e.what());
                }
            }
        }
        LOG_DEBUG(LOG, "dataEventReceived return %d", reclaim);
    }


Generated by  Doxygen 1.6.0   Back to index