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");
}
}
}
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;
}
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");
}
}
}
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");
}
}
}
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);
}
Aggregations