Example #1
0
  @VisibleForTesting
  public synchronized void acknowledge(String outputId, long sequenceId) {
    Preconditions.checkNotNull(outputId, "outputId is null");

    NamedQueue namedQueue = namedQueues.get(outputId);
    if (namedQueue == null) {
      throw new NoSuchBufferException(outputId, namedQueues.keySet());
    }

    if (state == QueueState.FINISHED) {
      return;
    }

    // remove queue from set before calling getPages because getPages changes
    // the sequence number of the queue which is used for identity comparison in the
    // sorted set
    openQueuesBySequenceId.remove(namedQueue);

    // acknowledge the pages
    namedQueue.acknowledge(sequenceId);

    // only add back the queue if it is still open
    if (!closed.get()) {
      openQueuesBySequenceId.add(namedQueue);
    } else {
      namedQueue.setFinished();
    }

    updateState();
  }
Example #2
0
  public synchronized void abort(String outputId) {
    Preconditions.checkNotNull(outputId, "outputId is null");
    NamedQueue namedQueue = namedQueues.get(outputId);
    if (namedQueue == null || namedQueue.isFinished()) {
      return;
    }
    namedQueue.setFinished();
    openQueuesBySequenceId.remove(namedQueue);

    updateState();
  }
Example #3
0
 public synchronized SharedBufferInfo getInfo() {
   ImmutableList.Builder<BufferInfo> infos = ImmutableList.builder();
   for (NamedQueue namedQueue : namedQueues.values()) {
     infos.add(
         new BufferInfo(
             namedQueue.getQueueId(),
             namedQueue.isFinished(),
             namedQueue.size(),
             namedQueue.pagesRemoved()));
   }
   return new SharedBufferInfo(state, masterSequenceId, pagesAdded.get(), infos.build());
 }
Example #4
0
  private synchronized void updateState() {
    if (closed.get()) {
      // remove all empty queues
      for (Iterator<NamedQueue> iterator = openQueuesBySequenceId.iterator();
          iterator.hasNext(); ) {
        NamedQueue namedQueue = iterator.next();
        if (namedQueue.isEmpty()) {
          namedQueue.setFinished();
          iterator.remove();
        }
      }
      // discard queued pages (not officially in the buffer) and waiters
      for (QueuedPage queuedPage : queuedPages) {
        queuedPage.getFuture().set(null);
      }
      queuedPages.clear();
    }

    if (state == QueueState.NO_MORE_QUEUES && !openQueuesBySequenceId.isEmpty()) {
      // advance master sequence id
      long oldMasterSequenceId = masterSequenceId;
      masterSequenceId = openQueuesBySequenceId.iterator().next().getSequenceId();

      // drop consumed pages
      int pagesToRemove = Ints.checkedCast(masterSequenceId - oldMasterSequenceId);
      Preconditions.checkState(
          pagesToRemove >= 0,
          "Master sequence id moved backwards: oldMasterSequenceId=%s, newMasterSequenceId=%s",
          oldMasterSequenceId,
          masterSequenceId);

      for (int i = 0; i < pagesToRemove; i++) {
        Page page = masterQueue.removeFirst();
        bufferedBytes -= page.getDataSize().toBytes();
      }

      // refill buffer from queued pages
      while (!queuedPages.isEmpty() && bufferedBytes < maxBufferedBytes) {
        QueuedPage queuedPage = queuedPages.removeFirst();
        addInternal(queuedPage.getPage());
        queuedPage.getFuture().set(null);
      }
    }

    if (state == QueueState.NO_MORE_QUEUES && closed.get() && openQueuesBySequenceId.isEmpty()) {
      destroy();
    }

    this.notifyAll();
  }
Example #5
0
  /** Destroys the queue, discarding all pages. */
  public synchronized void destroy() {
    closed.set(true);
    state = QueueState.FINISHED;

    // drop all of the queues
    for (NamedQueue namedQueue : openQueuesBySequenceId) {
      namedQueue.setFinished();
    }
    openQueuesBySequenceId.clear();

    // clear the buffer
    masterQueue.clear();
    bufferedBytes = 0;

    // free queued page waiters
    for (QueuedPage queuedPage : queuedPages) {
      queuedPage.getFuture().set(null);
    }
    queuedPages.clear();

    // notify readers that the buffer has been destroyed
    this.notifyAll();
  }
Example #6
0
  public synchronized BufferResult get(
      String outputId, long startingSequenceId, DataSize maxSize, Duration maxWait)
      throws InterruptedException {
    Preconditions.checkNotNull(outputId, "outputId is null");
    Preconditions.checkArgument(maxSize.toBytes() > 0, "maxSize must be at least 1 byte");
    Preconditions.checkNotNull(maxWait, "maxWait is null");

    NamedQueue namedQueue = namedQueues.get(outputId);
    if (namedQueue == null) {
      throw new NoSuchBufferException(outputId, namedQueues.keySet());
    }

    if (state == QueueState.FINISHED) {
      return emptyResults(namedQueue.getSequenceId(), true);
    }

    // wait for pages to arrive
    if (namedQueue.isEmpty()) {
      long remainingNanos = maxWait.roundTo(NANOSECONDS);
      long end = System.nanoTime() + remainingNanos;
      while (remainingNanos > 0 && namedQueue.isEmpty() && !namedQueue.isFinished()) {
        // wait for timeout or notification
        NANOSECONDS.timedWait(this, remainingNanos);
        remainingNanos = end - System.nanoTime();
      }
    }

    // remove queue from set before calling getPages because getPages changes
    // the sequence number of the queue which is used for identity comparison in the
    // sorted set
    openQueuesBySequenceId.remove(namedQueue);

    // get the pages
    BufferResult results = namedQueue.getPages(startingSequenceId, maxSize);

    // only add back the queue if it is still open
    if (!closed.get() || !results.isBufferClosed()) {
      openQueuesBySequenceId.add(namedQueue);
    } else {
      namedQueue.setFinished();
    }

    updateState();

    return results;
  }