#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 есть другой способ сборки процессора. Я имею в виду, что в вашем примере вы печатаете объекты, которые я хочу заполнить, два разных типа объектов. До сих пор я не нашел способа сделать это, используя методы в том же прослушивателе.