public void get() throws WriteTimeoutException, WriteFailureException {
    long requestTimeout =
        writeType == WriteType.COUNTER
            ? DatabaseDescriptor.getCounterWriteRpcTimeout()
            : DatabaseDescriptor.getWriteRpcTimeout();

    long timeout = TimeUnit.MILLISECONDS.toNanos(requestTimeout) - (System.nanoTime() - start);

    boolean success;
    try {
      success = condition.await(timeout, TimeUnit.NANOSECONDS);
    } catch (InterruptedException ex) {
      throw new AssertionError(ex);
    }

    if (!success) {
      int blockedFor = totalBlockFor();
      int acks = ackCount();
      // It's pretty unlikely, but we can race between exiting await above and here, so
      // that we could now have enough acks. In that case, we "lie" on the acks count to
      // avoid sending confusing info to the user (see CASSANDRA-6491).
      if (acks >= blockedFor) acks = blockedFor - 1;
      throw new WriteTimeoutException(writeType, consistencyLevel, acks, blockedFor);
    }

    if (totalBlockFor() + failures > totalEndpoints()) {
      throw new WriteFailureException(
          consistencyLevel, ackCount(), failures, totalBlockFor(), writeType);
    }
  }
 /** @param callback A callback to be called when the write is successful. */
 protected AbstractWriteResponseHandler(
     Keyspace keyspace,
     Collection<InetAddress> naturalEndpoints,
     Collection<InetAddress> pendingEndpoints,
     ConsistencyLevel consistencyLevel,
     Runnable callback,
     WriteType writeType) {
   this.keyspace = keyspace;
   this.pendingEndpoints = pendingEndpoints;
   this.start = System.nanoTime();
   this.consistencyLevel = consistencyLevel;
   this.naturalEndpoints = naturalEndpoints;
   this.callback = callback;
   this.writeType = writeType;
 }