Java 使用任一策略将记录发送到消息传递队列

Java 使用任一策略将记录发送到消息传递队列,java,algorithm,oop,design-patterns,Java,Algorithm,Oop,Design Patterns,我有一堆密钥(clientKey)和值(processBytes),我想通过将它们打包在一个字节数组中发送到消息队列。我将为所有键和值创建一个字节数组,这些键和值应始终小于50K,然后发送到我们的消息队列 对于每个分区,我有一堆数据持有者,因此我迭代这些数据持有者,然后将其发送到我的消息队列:- private void validateAndSend(final DataPartition partition) { final ConcurrentLinkedQueue<DataHo

我有一堆密钥
(clientKey)
和值
(processBytes)
,我想通过将它们打包在一个字节数组中发送到消息队列。我将为所有键和值创建一个字节数组,这些键和值应始终小于50K,然后发送到我们的消息队列

对于每个分区,我有一堆
数据持有者
,因此我迭代这些数据持有者,然后将其发送到我的消息队列:-

private void validateAndSend(final DataPartition partition) {
  final ConcurrentLinkedQueue<DataHolder> dataHolders = dataHoldersByPartition.get(partition);

  // sending data via async policy but it can be send with other two sync queue policy as well.
  final Packet packet = new Packet(partition, new QPolicyAsync());

  DataHolder dataHolder;
  while ((dataHolder = dataHolders.poll()) != null) {
    packet.addAndSendJunked(dataHolder.getClientKey().getBytes(StandardCharsets.UTF_8),
        dataHolder.getProcessBytes());
  }
  packet.close();
}
现在,我可以用三种不同的方式将数据发送到消息队列,为此我创建了一个接口,然后有三种不同的实现:

队列策略
接口

public interface QueuePolicy {
    public boolean sendToQueue(final long address, final byte[] encodedRecords);
}
public class QPolicyAsync implements QueuePolicy {

  @Override
  public boolean sendToQueue(long address, byte[] encodedRecords) {
    return SendRecord.getInstance().sendToQueueAsync(address, encodedRecords);
  }
}
public class QPolicySync implements QueuePolicy {

  @Override
  public boolean sendToQueue(long address, byte[] encodedRecords) {
    return SendRecord.getInstance().sendToQueueSync(address, encodedRecords);
  }
}
public class QPolicySyncWithSocket implements QueuePolicy {
  private final Socket socket;

  public QPolicySyncWithSocket(Socket socket) {
    this.socket = socket;
  }

  @Override
  public boolean sendToQueue(long address, byte[] encodedRecords) {
    return SendRecord.getInstance().sendToQueueSync(address, encodedRecords, Optional.of(socket));
  }
}
QpolicySync
class

public interface QueuePolicy {
    public boolean sendToQueue(final long address, final byte[] encodedRecords);
}
public class QPolicyAsync implements QueuePolicy {

  @Override
  public boolean sendToQueue(long address, byte[] encodedRecords) {
    return SendRecord.getInstance().sendToQueueAsync(address, encodedRecords);
  }
}
public class QPolicySync implements QueuePolicy {

  @Override
  public boolean sendToQueue(long address, byte[] encodedRecords) {
    return SendRecord.getInstance().sendToQueueSync(address, encodedRecords);
  }
}
public class QPolicySyncWithSocket implements QueuePolicy {
  private final Socket socket;

  public QPolicySyncWithSocket(Socket socket) {
    this.socket = socket;
  }

  @Override
  public boolean sendToQueue(long address, byte[] encodedRecords) {
    return SendRecord.getInstance().sendToQueueSync(address, encodedRecords, Optional.of(socket));
  }
}
QPolicySync
class

public interface QueuePolicy {
    public boolean sendToQueue(final long address, final byte[] encodedRecords);
}
public class QPolicyAsync implements QueuePolicy {

  @Override
  public boolean sendToQueue(long address, byte[] encodedRecords) {
    return SendRecord.getInstance().sendToQueueAsync(address, encodedRecords);
  }
}
public class QPolicySync implements QueuePolicy {

  @Override
  public boolean sendToQueue(long address, byte[] encodedRecords) {
    return SendRecord.getInstance().sendToQueueSync(address, encodedRecords);
  }
}
public class QPolicySyncWithSocket implements QueuePolicy {
  private final Socket socket;

  public QPolicySyncWithSocket(Socket socket) {
    this.socket = socket;
  }

  @Override
  public boolean sendToQueue(long address, byte[] encodedRecords) {
    return SendRecord.getInstance().sendToQueueSync(address, encodedRecords, Optional.of(socket));
  }
}
qpolicycynchwithsocket
class

public interface QueuePolicy {
    public boolean sendToQueue(final long address, final byte[] encodedRecords);
}
public class QPolicyAsync implements QueuePolicy {

  @Override
  public boolean sendToQueue(long address, byte[] encodedRecords) {
    return SendRecord.getInstance().sendToQueueAsync(address, encodedRecords);
  }
}
public class QPolicySync implements QueuePolicy {

  @Override
  public boolean sendToQueue(long address, byte[] encodedRecords) {
    return SendRecord.getInstance().sendToQueueSync(address, encodedRecords);
  }
}
public class QPolicySyncWithSocket implements QueuePolicy {
  private final Socket socket;

  public QPolicySyncWithSocket(Socket socket) {
    this.socket = socket;
  }

  @Override
  public boolean sendToQueue(long address, byte[] encodedRecords) {
    return SendRecord.getInstance().sendToQueueSync(address, encodedRecords, Optional.of(socket));
  }
}
想法非常简单:我通过这三种
QueuePolicy
实现中的任何一种向消息传递队列发送数据。这取决于客户端希望如何发送数据。现在,我正在
数据包
构造函数中传递
队列策略
的实现,然后通过该策略发送数据。每个
QueuePolicy
实现在
SendRecord
类中调用相应的方法


现在我需要知道数据是否成功发送。到目前为止,
Packet
类中的方法不返回任何布尔值,因此我不知道它是否成功发送。我可以遇到这样的情况,
数据持有者
中只有一个元素,或者可以有多个元素

private void validateAndSend(final DataPartition partition) {
  final ConcurrentLinkedQueue<DataHolder> dataHolders = dataHoldersByPartition.get(partition);

  // sending data via async policy but it can be send with other two sync queue policy as well.
  final Packet packet = new Packet(partition, new QPolicyAsync());

  DataHolder dataHolder;
  while ((dataHolder = dataHolders.poll()) != null) {
    packet.addAndSendJunked(dataHolder.getClientKey().getBytes(StandardCharsets.UTF_8),
        dataHolder.getProcessBytes());
  }
  packet.close();
  // how do I know whether this data was successfully sent?

}

无法从
close()
方法返回布尔值,因为它已被重写

您有不同的选择:

  • 每当发送返回false时引发异常
  • sendData
    返回一个布尔值,我会将其重命名为
    flush
    并将其公开(见下文),并从
    addAndSendJunked
    返回一个布尔值
  • 在class
    Packet
    中添加一个布尔字段和一个getter,以便能够随时获取其值
  • 方法
    flush

    public boolean flush() {
        if (itemBuffer.position() == 0) {
            // no data to be sent
            return true;
        }
        final ByteBuffer buffer = ByteBuffer.allocate(MAX_SIZE);
        addHeader(buffer, pendingItems);
        buffer.put(itemBuffer);
        // sending data via particular policy
        boolean result = policy.sendToQueue(address, buffer.array());
        itemBuffer.clear();
        pendingItems = 0;
        return result;
    }
    

    你能告诉我为什么
    flush
    方法需要在这里公开吗?在我的例子中,没有人从
    Packet
    类之外调用该方法。我也用你的建议更新了这个问题。你认为这是对的还是我可以做一些其他的改变?我正在从flush方法返回一个布尔值,并且在
    Packet
    类及其getter中有一个布尔变量。@user1950349
    flush
    是公共的,因为它在不能返回布尔值的
    close
    中使用<如果您想知道发送的结果,应该直接调用code>flush。