Хроническая очередь чтения любого сообщения с readDocument

#chronicle #chronicle-queue #chronicle-bytes

#хроника #хроника-очередь #хроника-байты

Вопрос:

В очереди хроники у меня записаны два типа сообщений. Я хочу прочитать эти сообщения, используя тот же tailer и, если это возможно, с помощью того же метода, например, с помощью tailer.readDocument().

Кто-нибудь теперь, если это возможно, типы сообщений относятся к объектам разного типа. У них нет никаких отношений.

В моей реальной логике чтения мне нужно прочитать все записи очереди, и порядок важен, например:

Очередь MessageA MessageA MessageB

В этом примере мне нужно прочитать сообщение B только после сообщения A, поэтому я ищу метод, который считывает все записи независимо от типа сообщения.

Ответ №1:

Самый простой подход — записывать сообщения с помощью MethodWriter / MethodReader https://github.com/OpenHFT/Chronicle-Queue#high-level-interface

Вы начинаете с определения асинхронного интерфейса, где все методы имеют:

  • аргументы, которые являются только входными данными
  • возвращаемое значение или исключения не ожидаются.

Простой асинхронный интерфейс

 import net.openhft.chronicle.wire.SelfDescribingMarshallable;
interface MessageListener {
    void method1(Message1 message);

    void method2(Message2 message);
}

static class Message1 extends SelfDescribingMarshallable {
    String text;

    public Message1(String text) {
        this.text = text;
    }
}

static class Message2 extends SelfDescribingMarshallable {
    long number;

    public Message2(long number) {
        this.number = number;
    }
}
 

Для записи в очередь вы можете вызвать прокси, который реализует этот интерфейс.

 SingleChronicleQueue queue1 = ChronicleQueue.singleBuilder(path).build();

MessageListener writer1 = queue1.acquireAppender().methodWriter(MessageListener.class);

// call method on the interface to send messages
writer1.method1(new Message1("hello"));
writer1.method2(new Message2(234));
 

Эти вызовы выдают сообщения, которые могут быть сброшены следующим образом.

 # position: 262568, header: 0
--- !!data #binary
method1: {
  text: hello
}
# position: 262597, header: 1
--- !!data #binary
method2: {
  number: !int 234
}
 

Чтобы прочитать сообщения, вы можете предоставить средство чтения, которое вызывает вашу реализацию с теми же вызовами, которые вы сделали.

 // a proxy which print each method called on it
MessageListener processor = ObjectUtils.printAll(MessageListener.class)
// a queue reader which turns messages into method calls.
MethodReader reader1 = queue1.createTailer().methodReader(processor);

assertTrue(reader1.readOne());
assertTrue(reader1.readOne());
assertFalse(reader1.readOne());
 

Выполнение этого примера выводит:

 method1 [!Message1 {
  text: hello
}
]
method2 [!Message2 {
  number: 234
}
]
 

Ответ №2:

У Nice @PeterLawrey есть другой способ сборки процессора. Я имею в виду, что в вашем примере вы печатаете объекты, которые я хочу заполнить, два разных типа объектов. До сих пор я не нашел способа сделать это, используя методы в том же прослушивателе.