private void chooseSlotToTake() throws Exception {
    int slotToTake = -1;
    while (true) {
      List<String> allChildNodes;
      try {
        allChildNodes = client.getChildren().forPath(basePath);
      } catch (Exception e) {
        LOG.error("Cannot list nodes to get slots; failing", e);
        throw e;
      }
      TreeSet<Integer> slots = new TreeSet<>();
      int approxWorkerCount = 0;
      for (String child : allChildNodes) {
        if (!child.startsWith(prefix)) {
          if (child.startsWith(workerPrefix)) {
            ++approxWorkerCount;
          }
        } else {
          slots.add(Integer.parseInt(child.substring(prefix.length())));
        }
      }
      Iterator<Integer> slotIter = slots.iterator();
      slotToTake = 0;
      while (slotIter.hasNext()) {
        int nextTaken = slotIter.next();
        if (slotToTake < nextTaken) break;
        slotToTake = nextTaken + 1;
      }
      // There may be a race for this slot so re-query after a delay with some probability.
      if (slotToTake != currentSlot || !shouldFallBackOnCollision(approxWorkerCount)) break;
      ++fallbackCount;
      Thread.sleep(rdm.nextInt(200)); // arbitrary
    }

    currentSlot = slotToTake;
    LOG.info("Will attempt to take slot " + currentSlot);
  }
We would have used the curator ephemeral node with some extra logic but it doesn't handle
the EXISTS condition, which is crucial here; so we c/p parts of Curator and add our logic.
llap-client/src/java/org/apache/hadoop/hive/llap/registry/impl/SlotZnode.java