Chronicle Queue:如何使用不同的 WireKey 读取 excepts/documents?

Chronicle Queue: How to read excepts/documents with different WireKey?

假设有一个编年史队列,以及一个将两种类型的消息写入队列的生产者。 每种类型的消息都使用不同的“WireKey”写入。

// Writes: {key1: TestMessage}
appender.writeDocument(w -> w.write("key1").text("TestMessage"));

// Writes: {key2: AnotherTextMessage}
appender.writeDocument(w -> w.write("key2").text("AnotherTextMessage"));

问题:

如何编写可以读取两种类型的消息并以不同方式处理它们的单线程使用者?

我试过的:

// This can read both types of messages, but cannot
// tell which type a message belongs to.
tailer.readDocument(wire -> {
    wire.read().text();
});
// This only reads type "key1" messages, skips all "key2" messages.
tailer.readDocument(wire -> {
    wire.read("key1").text();
});
// This crashes. (because it advances the read position illegally?)
tailer.readDocument(wire -> {
    wire.read("key1").text();
    wire.read("key2").text();
});

我希望我可以做类似 wire.readKey() 的事情并获取文档的 WireKey,然后继续读取文档并动态处理它。我该怎么做?

注意:我知道这可以使用 methodReadermethodWriter 来完成,而且 documentation/demo 似乎推荐这种方法 (?) 但我不想这样做使用 API,并明确读取和写入消息。我假设必须有一种方法来完成这个用例。

谢谢。

你是对的,例如MethodReader 完成它。

有两种方法

// a reused StringBuilder
StringBuilder sb = new StringBuilder();
wire.read(sb); // populate the StringBuilder

或者更方便的方法是

String name = wire.readEvent(String.class);
switch(name) {
    case "key1":
        String text1 = wire.getValueIn().text();
        // do something with text1
        break;

    case "key2":
        String text2 = wire.getValueIn().text();
        // do something with text1
        break;

    default:
        // log unexpected key
}

对于不了解 MethodReader 的其他读者,可以使用

完成相同的消息
interface MyEvents {
    void key1(String text1);
    void key2(String text2);
}

MyEvents me = wire.methodWriter(MyEvents.class);
me.key1("text1");
me.key2("text2");

MyEvents me2 = new MyEvents() {
    public void key1(String text1) {
        // handle text1
    }
    public void key2(String text2) {
        // handle text2
    }
};

Reader reader = wire.methodReader(MyEevents.class);
do {
} while(reader.readeOne());

注意:内容相同,因此您可以混合搭配这两个选项

您可以使用 Chronicle Queue 而不是 Wire 来保存此信息