All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.rabbitmq.stream.impl.SimpleMessageAccumulator Maven / Gradle / Ivy

// Copyright (c) 2020-2021 VMware, Inc. or its affiliates.  All rights reserved.
//
// This software, the RabbitMQ Stream Java client library, is dual-licensed under the
// Mozilla Public License 2.0 ("MPL"), and the Apache License version 2 ("ASL").
// For the MPL, please see LICENSE-MPL-RabbitMQ. For the ASL,
// please see LICENSE-APACHE2.
//
// This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND,
// either express or implied. See the LICENSE file for specific language governing
// rights and limitations of this software.
//
// If you have any questions regarding licensing, please contact us at
// [email protected].
package com.rabbitmq.stream.impl;

import com.rabbitmq.stream.Codec;
import com.rabbitmq.stream.ConfirmationHandler;
import com.rabbitmq.stream.ConfirmationStatus;
import com.rabbitmq.stream.Message;
import com.rabbitmq.stream.StreamException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.function.ToLongFunction;

class SimpleMessageAccumulator implements MessageAccumulator {

  protected final BlockingQueue messages;
  protected final Clock clock;
  private final int capacity;
  private final Codec codec;
  private final int maxFrameSize;
  private final ToLongFunction publishSequenceFunction;

  SimpleMessageAccumulator(
      int capacity,
      Codec codec,
      int maxFrameSize,
      ToLongFunction publishSequenceFunction,
      Clock clock) {
    this.capacity = capacity;
    this.messages = new LinkedBlockingQueue<>(capacity);
    this.codec = codec;
    this.maxFrameSize = maxFrameSize;
    this.publishSequenceFunction = publishSequenceFunction;
    this.clock = clock;
  }

  public boolean add(Message message, ConfirmationHandler confirmationHandler) {
    Codec.EncodedMessage encodedMessage = this.codec.encode(message);
    Client.checkMessageFitsInFrame(this.maxFrameSize, encodedMessage);
    long publishingId = this.publishSequenceFunction.applyAsLong(message);
    try {
      boolean offered =
          messages.offer(
              new SimpleAccumulatedEntity(
                  clock.time(),
                  publishingId,
                  encodedMessage,
                  new SimpleConfirmationCallback(message, confirmationHandler)),
              60,
              TimeUnit.SECONDS);
      if (!offered) {
        throw new StreamException("Could not accumulate outbound message");
      }
    } catch (InterruptedException e) {
      throw new StreamException("Error while accumulating outbound message", e);
    }
    return this.messages.size() == this.capacity;
  }

  @Override
  public AccumulatedEntity get() {
    return this.messages.poll();
  }

  @Override
  public boolean isEmpty() {
    return messages.isEmpty();
  }

  @Override
  public int size() {
    return messages.size();
  }

  private static final class SimpleAccumulatedEntity implements AccumulatedEntity {

    private final long time;
    private final long publishingId;
    private final Codec.EncodedMessage encodedMessage;
    private final StreamProducer.ConfirmationCallback confirmationCallback;

    private SimpleAccumulatedEntity(
        long time,
        long publishingId,
        Codec.EncodedMessage encodedMessage,
        StreamProducer.ConfirmationCallback confirmationCallback) {
      this.time = time;
      this.publishingId = publishingId;
      this.encodedMessage = encodedMessage;
      this.confirmationCallback = confirmationCallback;
    }

    @Override
    public long publishindId() {
      return publishingId;
    }

    @Override
    public Object encodedEntity() {
      return encodedMessage;
    }

    @Override
    public long time() {
      return time;
    }

    @Override
    public StreamProducer.ConfirmationCallback confirmationCallback() {
      return confirmationCallback;
    }
  }

  private static final class SimpleConfirmationCallback
      implements StreamProducer.ConfirmationCallback {

    private final Message message;
    private final ConfirmationHandler confirmationHandler;

    private SimpleConfirmationCallback(Message message, ConfirmationHandler confirmationHandler) {
      this.message = message;
      this.confirmationHandler = confirmationHandler;
    }

    @Override
    public int handle(boolean confirmed, short code) {
      confirmationHandler.handle(new ConfirmationStatus(message, confirmed, code));
      return 1;
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy