docs: public void updateTopology(final PackingPlans.PackingPlan existingProtoPackingPlan,
                               final PackingPlans.PackingPlan proposedProtoPackingPlan)
        throws ExecutionException, InterruptedException, ConcurrentModificationException {
      String topologyName = Runtime.topologyName(runtime);
      SchedulerStateManagerAdaptor stateManager = Runtime.schedulerStateManagerAdaptor(runtime);
      Lock lock = stateManager.getLock(topologyName, IStateManager.LockName.UPDATE_TOPOLOGY);
  
      if (lock.tryLock(5, TimeUnit.SECONDS)) {
        try {
          PackingPlans.PackingPlan foundPackingPlan = getPackingPlan(stateManager, topologyName);
  
          if (!deserializer.fromProto(existingProtoPackingPlan)
              .equals(deserializer.fromProto(foundPackingPlan))) {
            throw new ConcurrentModificationException(String.format(
                "The packing plan in state manager is not the same as the submitted existing "
                    + "packing plan for topology %s. Another actor has changed it and has likely"
                    + "performed an update on it. Failing this request, try again once other "
                    + "update is complete", topologyName));
          }
  
          updateTopology(existingProtoPackingPlan, proposedProtoPackingPlan, stateManager);
        } finally {
          lock.unlock();
        }
      } else {
        throw new ConcurrentModificationException(String.format(
            "The update lock can not be obtained for topology %s. Another actor is performing an "
                + "update on it. Failing this request, try again once current update is complete",
            topologyName));
      }
    }