Search in sources :

Example 1 with CreateCallbackHandler

use of org.apache.helix.manager.zk.ZkAsyncCallbacks.CreateCallbackHandler in project helix by apache.

the class ZkBaseDataAccessor method update.

/**
 * async update
 * return: updatedData on success or null on fail
 */
List<T> update(List<String> paths, List<DataUpdater<T>> updaters, List<List<String>> pathsCreated, List<Stat> stats, int options) {
    if (paths == null || paths.size() == 0) {
        LOG.error("paths is null or empty");
        return Collections.emptyList();
    }
    if (updaters.size() != paths.size() || (pathsCreated != null && pathsCreated.size() != paths.size())) {
        throw new IllegalArgumentException("paths, updaters, and pathsCreated should be of same size");
    }
    List<Stat> setStats = new ArrayList<Stat>(Collections.<Stat>nCopies(paths.size(), null));
    List<T> updateData = new ArrayList<T>(Collections.<T>nCopies(paths.size(), null));
    CreateMode mode = AccessOption.getMode(options);
    if (mode == null) {
        LOG.error("Invalid update mode. options: " + options);
        return updateData;
    }
    SetDataCallbackHandler[] cbList = new SetDataCallbackHandler[paths.size()];
    CreateCallbackHandler[] createCbList = null;
    boolean[] needUpdate = new boolean[paths.size()];
    Arrays.fill(needUpdate, true);
    long startT = System.nanoTime();
    try {
        boolean retry;
        do {
            retry = false;
            // init'ed with false
            boolean[] needCreate = new boolean[paths.size()];
            boolean failOnNoNode = false;
            // asycn read all data
            List<Stat> curStats = new ArrayList<Stat>();
            List<T> curDataList = get(paths, curStats, Arrays.copyOf(needUpdate, needUpdate.length), false);
            // async update
            List<T> newDataList = new ArrayList<T>();
            for (int i = 0; i < paths.size(); i++) {
                if (!needUpdate[i]) {
                    newDataList.add(null);
                    continue;
                }
                String path = paths.get(i);
                DataUpdater<T> updater = updaters.get(i);
                T newData = updater.update(curDataList.get(i));
                newDataList.add(newData);
                if (newData == null) {
                    // No need to create or update if the updater does not return a new version
                    continue;
                }
                Stat curStat = curStats.get(i);
                if (curStat == null) {
                    // node not exists
                    failOnNoNode = true;
                    needCreate[i] = true;
                } else {
                    cbList[i] = new SetDataCallbackHandler();
                    _zkClient.asyncSetData(path, newData, curStat.getVersion(), cbList[i]);
                }
            }
            // wait for completion
            boolean failOnBadVersion = false;
            for (int i = 0; i < paths.size(); i++) {
                SetDataCallbackHandler cb = cbList[i];
                if (cb == null)
                    continue;
                cb.waitForSuccess();
                switch(Code.get(cb.getRc())) {
                    case OK:
                        updateData.set(i, newDataList.get(i));
                        setStats.set(i, cb.getStat());
                        needUpdate[i] = false;
                        break;
                    case NONODE:
                        failOnNoNode = true;
                        needCreate[i] = true;
                        break;
                    case BADVERSION:
                        failOnBadVersion = true;
                        break;
                    default:
                        // if fail on error other than NoNode or BadVersion
                        // will not retry
                        needUpdate[i] = false;
                        break;
                }
            }
            // if failOnNoNode, try create
            if (failOnNoNode) {
                createCbList = create(paths, newDataList, needCreate, pathsCreated, options);
                for (int i = 0; i < paths.size(); i++) {
                    CreateCallbackHandler createCb = createCbList[i];
                    if (createCb == null) {
                        continue;
                    }
                    switch(Code.get(createCb.getRc())) {
                        case OK:
                            needUpdate[i] = false;
                            updateData.set(i, newDataList.get(i));
                            setStats.set(i, ZNode.ZERO_STAT);
                            break;
                        case NODEEXISTS:
                            retry = true;
                            break;
                        default:
                            // if fail on error other than NodeExists
                            // will not retry
                            needUpdate[i] = false;
                            break;
                    }
                }
            }
            // if failOnBadVersion, retry
            if (failOnBadVersion) {
                retry = true;
            }
        } while (retry);
        if (stats != null) {
            stats.clear();
            stats.addAll(setStats);
        }
        return updateData;
    } finally {
        long endT = System.nanoTime();
        if (LOG.isTraceEnabled()) {
            LOG.trace("setData_async, size: " + paths.size() + ", paths: " + paths.get(0) + ",... time: " + (endT - startT) + " ns");
        }
    }
}
Also used : ArrayList(java.util.ArrayList) CreateCallbackHandler(org.apache.helix.manager.zk.ZkAsyncCallbacks.CreateCallbackHandler) SetDataCallbackHandler(org.apache.helix.manager.zk.ZkAsyncCallbacks.SetDataCallbackHandler) Stat(org.apache.zookeeper.data.Stat) CreateMode(org.apache.zookeeper.CreateMode)

Example 2 with CreateCallbackHandler

use of org.apache.helix.manager.zk.ZkAsyncCallbacks.CreateCallbackHandler in project helix by apache.

the class ZkBaseDataAccessor method create.

/**
 * async create. give up on error other than NONODE
 */
CreateCallbackHandler[] create(List<String> paths, List<T> records, boolean[] needCreate, List<List<String>> pathsCreated, int options) {
    if ((records != null && records.size() != paths.size()) || needCreate.length != paths.size() || (pathsCreated != null && pathsCreated.size() != paths.size())) {
        throw new IllegalArgumentException("paths, records, needCreate, and pathsCreated should be of same size");
    }
    CreateCallbackHandler[] cbList = new CreateCallbackHandler[paths.size()];
    CreateMode mode = AccessOption.getMode(options);
    if (mode == null) {
        LOG.error("Invalid async set mode. options: " + options);
        return cbList;
    }
    boolean retry;
    do {
        retry = false;
        for (int i = 0; i < paths.size(); i++) {
            if (!needCreate[i])
                continue;
            String path = paths.get(i);
            T record = records == null ? null : records.get(i);
            cbList[i] = new CreateCallbackHandler();
            _zkClient.asyncCreate(path, record, mode, cbList[i]);
        }
        List<String> parentPaths = new ArrayList<String>(Collections.<String>nCopies(paths.size(), null));
        boolean failOnNoNode = false;
        for (int i = 0; i < paths.size(); i++) {
            if (!needCreate[i])
                continue;
            CreateCallbackHandler cb = cbList[i];
            cb.waitForSuccess();
            String path = paths.get(i);
            if (Code.get(cb.getRc()) == Code.NONODE) {
                String parentPath = HelixUtil.getZkParentPath(path);
                parentPaths.set(i, parentPath);
                failOnNoNode = true;
            } else {
                // if create succeed or fail on error other than NONODE,
                // give up
                needCreate[i] = false;
                // if succeeds, record what paths we've created
                if (Code.get(cb.getRc()) == Code.OK && pathsCreated != null) {
                    if (pathsCreated.get(i) == null) {
                        pathsCreated.set(i, new ArrayList<String>());
                    }
                    pathsCreated.get(i).add(path);
                }
            }
        }
        if (failOnNoNode) {
            boolean[] needCreateParent = Arrays.copyOf(needCreate, needCreate.length);
            CreateCallbackHandler[] parentCbList = create(parentPaths, null, needCreateParent, pathsCreated, AccessOption.PERSISTENT);
            for (int i = 0; i < parentCbList.length; i++) {
                CreateCallbackHandler parentCb = parentCbList[i];
                if (parentCb == null)
                    continue;
                Code rc = Code.get(parentCb.getRc());
                // if parent is created, retry create child
                if (rc == Code.OK || rc == Code.NODEEXISTS) {
                    retry = true;
                    break;
                }
            }
        }
    } while (retry);
    return cbList;
}
Also used : ArrayList(java.util.ArrayList) CreateCallbackHandler(org.apache.helix.manager.zk.ZkAsyncCallbacks.CreateCallbackHandler) Code(org.apache.zookeeper.KeeperException.Code) CreateMode(org.apache.zookeeper.CreateMode)

Example 3 with CreateCallbackHandler

use of org.apache.helix.manager.zk.ZkAsyncCallbacks.CreateCallbackHandler in project helix by apache.

the class ZkBaseDataAccessor method createChildren.

/**
 * async create
 * TODO: rename to create
 */
@Override
public boolean[] createChildren(List<String> paths, List<T> records, int options) {
    boolean[] success = new boolean[paths.size()];
    CreateMode mode = AccessOption.getMode(options);
    if (mode == null) {
        LOG.error("Invalid async create mode. options: " + options);
        return success;
    }
    boolean[] needCreate = new boolean[paths.size()];
    Arrays.fill(needCreate, true);
    List<List<String>> pathsCreated = new ArrayList<List<String>>(Collections.<List<String>>nCopies(paths.size(), null));
    long startT = System.nanoTime();
    try {
        CreateCallbackHandler[] cbList = create(paths, records, needCreate, pathsCreated, options);
        for (int i = 0; i < cbList.length; i++) {
            CreateCallbackHandler cb = cbList[i];
            success[i] = (Code.get(cb.getRc()) == Code.OK);
        }
        return success;
    } finally {
        long endT = System.nanoTime();
        if (LOG.isTraceEnabled()) {
            LOG.trace("create_async, size: " + paths.size() + ", paths: " + paths.get(0) + ",... time: " + (endT - startT) + " ns");
        }
    }
}
Also used : CreateMode(org.apache.zookeeper.CreateMode) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) CreateCallbackHandler(org.apache.helix.manager.zk.ZkAsyncCallbacks.CreateCallbackHandler)

Example 4 with CreateCallbackHandler

use of org.apache.helix.manager.zk.ZkAsyncCallbacks.CreateCallbackHandler in project helix by apache.

the class ZkBaseDataAccessor method set.

/**
 * async set, give up on error other than NoNode
 */
boolean[] set(List<String> paths, List<T> records, List<List<String>> pathsCreated, List<Stat> stats, int options) {
    if (paths == null || paths.size() == 0) {
        return new boolean[0];
    }
    if ((records != null && records.size() != paths.size()) || (pathsCreated != null && pathsCreated.size() != paths.size())) {
        throw new IllegalArgumentException("paths, records, and pathsCreated should be of same size");
    }
    boolean[] success = new boolean[paths.size()];
    CreateMode mode = AccessOption.getMode(options);
    if (mode == null) {
        LOG.error("Invalid async set mode. options: " + options);
        return success;
    }
    List<Stat> setStats = new ArrayList<Stat>(Collections.<Stat>nCopies(paths.size(), null));
    SetDataCallbackHandler[] cbList = new SetDataCallbackHandler[paths.size()];
    CreateCallbackHandler[] createCbList = null;
    boolean[] needSet = new boolean[paths.size()];
    Arrays.fill(needSet, true);
    long startT = System.nanoTime();
    try {
        boolean retry;
        do {
            retry = false;
            for (int i = 0; i < paths.size(); i++) {
                if (!needSet[i])
                    continue;
                String path = paths.get(i);
                T record = records.get(i);
                cbList[i] = new SetDataCallbackHandler();
                _zkClient.asyncSetData(path, record, -1, cbList[i]);
            }
            boolean failOnNoNode = false;
            for (int i = 0; i < cbList.length; i++) {
                SetDataCallbackHandler cb = cbList[i];
                cb.waitForSuccess();
                Code rc = Code.get(cb.getRc());
                switch(rc) {
                    case OK:
                        setStats.set(i, cb.getStat());
                        needSet[i] = false;
                        break;
                    case NONODE:
                        // if fail on NoNode, try create the node
                        failOnNoNode = true;
                        break;
                    default:
                        // if fail on error other than NoNode, give up
                        needSet[i] = false;
                        break;
                }
            }
            // if failOnNoNode, try create
            if (failOnNoNode) {
                boolean[] needCreate = Arrays.copyOf(needSet, needSet.length);
                createCbList = create(paths, records, needCreate, pathsCreated, options);
                for (int i = 0; i < createCbList.length; i++) {
                    CreateCallbackHandler createCb = createCbList[i];
                    if (createCb == null) {
                        continue;
                    }
                    Code rc = Code.get(createCb.getRc());
                    switch(rc) {
                        case OK:
                            setStats.set(i, ZNode.ZERO_STAT);
                            needSet[i] = false;
                            break;
                        case NODEEXISTS:
                            retry = true;
                            break;
                        default:
                            // if creation fails on error other than NodeExists
                            // no need to retry set
                            needSet[i] = false;
                            break;
                    }
                }
            }
        } while (retry);
        // construct return results
        for (int i = 0; i < cbList.length; i++) {
            SetDataCallbackHandler cb = cbList[i];
            Code rc = Code.get(cb.getRc());
            if (rc == Code.OK) {
                success[i] = true;
            } else if (rc == Code.NONODE) {
                CreateCallbackHandler createCb = createCbList[i];
                if (Code.get(createCb.getRc()) == Code.OK) {
                    success[i] = true;
                }
            }
        }
        if (stats != null) {
            stats.clear();
            stats.addAll(setStats);
        }
        return success;
    } finally {
        long endT = System.nanoTime();
        if (LOG.isTraceEnabled()) {
            LOG.trace("setData_async, size: " + paths.size() + ", paths: " + paths.get(0) + ",... time: " + (endT - startT) + " ns");
        }
    }
}
Also used : ArrayList(java.util.ArrayList) CreateCallbackHandler(org.apache.helix.manager.zk.ZkAsyncCallbacks.CreateCallbackHandler) Code(org.apache.zookeeper.KeeperException.Code) SetDataCallbackHandler(org.apache.helix.manager.zk.ZkAsyncCallbacks.SetDataCallbackHandler) Stat(org.apache.zookeeper.data.Stat) CreateMode(org.apache.zookeeper.CreateMode)

Example 5 with CreateCallbackHandler

use of org.apache.helix.manager.zk.ZkAsyncCallbacks.CreateCallbackHandler in project helix by apache.

the class ZkCacheBaseDataAccessor method createChildren.

@Override
public boolean[] createChildren(List<String> paths, List<T> records, int options) {
    final int size = paths.size();
    List<String> serverPaths = prependChroot(paths);
    Cache<T> cache = getCache(serverPaths);
    if (cache != null) {
        try {
            cache.lockWrite();
            boolean[] needCreate = new boolean[size];
            Arrays.fill(needCreate, true);
            List<List<String>> pathsCreatedList = new ArrayList<List<String>>(Collections.<List<String>>nCopies(size, null));
            CreateCallbackHandler[] createCbList = _baseAccessor.create(serverPaths, records, needCreate, pathsCreatedList, options);
            boolean[] success = new boolean[size];
            for (int i = 0; i < size; i++) {
                CreateCallbackHandler cb = createCbList[i];
                success[i] = (Code.get(cb.getRc()) == Code.OK);
                updateCache(cache, pathsCreatedList.get(i), success[i], serverPaths.get(i), records.get(i), ZNode.ZERO_STAT);
            }
            return success;
        } finally {
            cache.unlockWrite();
        }
    }
    // no cache
    return _baseAccessor.createChildren(serverPaths, records, options);
}
Also used : ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) CreateCallbackHandler(org.apache.helix.manager.zk.ZkAsyncCallbacks.CreateCallbackHandler)

Aggregations

ArrayList (java.util.ArrayList)5 CreateCallbackHandler (org.apache.helix.manager.zk.ZkAsyncCallbacks.CreateCallbackHandler)5 CreateMode (org.apache.zookeeper.CreateMode)4 List (java.util.List)2 SetDataCallbackHandler (org.apache.helix.manager.zk.ZkAsyncCallbacks.SetDataCallbackHandler)2 Code (org.apache.zookeeper.KeeperException.Code)2 Stat (org.apache.zookeeper.data.Stat)2