/** * sync update * * @return: updatedData on success, or null on fail */ public T update( String path, DataUpdater<T> updater, List<String> createPaths, Stat stat, int options) { CreateMode mode = AccessOption.getMode(options); if (mode == null) { LOG.error("Invalid update mode. options: " + options); return null; } boolean retry; T updatedData = null; do { retry = false; try { Stat readStat = new Stat(); T oldData = (T) _zkClient.readData(path, readStat); T newData = updater.update(oldData); Stat setStat = _zkClient.writeDataGetStat(path, newData, readStat.getVersion()); if (stat != null) { DataTree.copyStat(setStat, stat); } updatedData = newData; } catch (ZkBadVersionException e) { retry = true; } catch (ZkNoNodeException e) { // node not exist, try create try { T newData = updater.update(null); RetCode rc = create(path, newData, createPaths, options); switch (rc) { case OK: updatedData = newData; break; case NODE_EXISTS: retry = true; break; default: LOG.error("Fail to update path by creating: " + path); return null; } } catch (Exception e1) { LOG.error("Exception while updating path by creating: " + path, e1); return null; } } catch (Exception e) { LOG.error("Exception while updating path: " + path, e); return null; } } while (retry); return updatedData; }
/** * sync set * * @param setstat : if node is created instead of set, stat will NOT be set */ public boolean set( String path, T record, List<String> pathsCreated, Stat setstat, int expectVersion, int options) { CreateMode mode = AccessOption.getMode(options); if (mode == null) { LOG.error("Invalid set mode. options: " + options); return false; } boolean retry; do { retry = false; try { // _zkClient.writeData(path, record); Stat setStat = _zkClient.writeDataGetStat(path, record, expectVersion); if (setstat != null) DataTree.copyStat(setStat, setstat); } catch (ZkNoNodeException e) { // node not exists, try create. in this case, stat will not be set try { RetCode rc = create(path, record, pathsCreated, options); // if (rc == RetCode.OK || rc == RetCode.NODE_EXISTS) // retry = true; switch (rc) { case OK: // not set stat if node is created (instead of set) break; case NODE_EXISTS: retry = true; break; default: LOG.error("Fail to set path by creating: " + path); return false; } } catch (Exception e1) { LOG.error("Exception while setting path by creating: " + path, e); return false; } } catch (ZkBadVersionException e) { throw e; } catch (Exception e) { LOG.error("Exception while setting path: " + path, e); return false; } } while (retry); return true; }