code: private void updateAccountWaitTime(long clientCustomerId, long waitForMillis) {
      final long minWaitTime = millisFromNow(waitForMillis);
  
      // Here we are assuming that the AtomicLong reference isn't changed once inserted. Therefore,
      // the content of this map grows with the number of account rate limits encountered. Future work
      // may address the problem of flushing this to reduce overall memory pressure.
      //
      // Overhead of AtomicLong is ~ size(long) 64 bytes,
      // if managing 100k customers this implies a total memory pressure of ~ 100000 * 64 = 6MB.
      //
      // Overhead of managing the map is 2 * 100k * (size(key) + size(reference)) = 24MB,
      // multiplying by factor of 2 to compensate for a map with 50% max load.
      //
      // An additional 36MB of RAM is a reasonable trade-off to simplify this implementation.
  
      AtomicLong recordedWaitTime =
          accountWaitUntil.computeIfAbsent(clientCustomerId, k -> new AtomicLong(minWaitTime));
  
      // This update algorithm will eventually terminate, but possibly not on the first iteration due
      // to concurrent updates. A better solution would be to use
      // AtomicLongMap.accumulateAndGet(K, long, LongBinaryOperator) from Guava 21.0, however this
      // would require bumping the Guava version for all Google Ads Java libraries and their
      // dependents.
      long snapshotTime = recordedWaitTime.get();
      while (snapshotTime < minWaitTime) {
        if (recordedWaitTime.compareAndSet(snapshotTime, minWaitTime)) {
          break;
        } else {
          snapshotTime = recordedWaitTime.get();
        }
      }
    }
docs: Update the wait time for ACCOUNT scope.
  
  @param clientCustomerId the client customer ID
  @param waitForMillis the wait time in milliseconds