【问题标题】:Chronicle Queue: How to read excepts/documents with different WireKey?Chronicle Queue:如何使用不同的 WireKey 读取异常/文档?
【发布时间】:2022-06-27 15:18:54
【问题描述】:

假设一个编年史队列和一个将两种类型的消息写入队列的生产者。 每种类型的消息都使用不同的“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 来完成,并且似乎文档/演示推荐了这种方法(?)但我不想使用那个 API,并明确说明读取和写入消息。我认为必须有一种方法来完成这个用例。

谢谢。

【问题讨论】:

    标签: chronicle chronicle-queue chronicle-wire


    【解决方案1】:

    你是对的,例如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(me2;
    do {
    } while(reader.readeOne());
    

    注意:内容是一样的,所以你可以混合搭配两个选项

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

    【讨论】:

    • wire.read().text()wire.getValueIn().text() 有什么区别? javadoc 似乎不鼓励getValueIn(),因为它被标记为“内部使用”
    • read() 需要一个事件键,尽管它并不关心它是哪一个。
    • @ccnlui 我几乎正好在 7 年前添加了该评论:P 也许“高级使用”是一个更好的描述。
    • 感谢彼得的回答。小问题:Reader reader = wire.methodReader(MyEevents.class); 不应该是Reader reader = wire.methodReader(me2); 吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多