Chronicle Queue reading any kind of message with readDocument

357 views Asked by At

In the Chronicle Queue I have two types of messages written. I wanna read this messages using the same tailer and if it is possible with the same method for example using tailer.readDocument().

Anyone now if it is possible, the message types are from different kind of objects. They haven't relationship.

In my actual reading logic I need to read all the entries of the queue and the order is important, for example:

Queue MessageA MessageA MessageB

I need to read message B only after message A in this example, because of that I am looking for a method that read all the entries independent of message type.

2

There are 2 answers

0
Peter Lawrey On

The simplest approach is to write messages using a MethodWriter/MethodReader https://github.com/OpenHFT/Chronicle-Queue#high-level-interface

You start by defining an asynchronous interface, where all methods have:

  • arguments which are only inputs
  • no return value or exceptions expected.

A simple asynchronous 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;
    }
}

To write to the queue you can call a proxy that implements this interface.

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));

These calls produce messages which can be dumped as follows.

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

To read the messages, you can provide a reader which calls your implementation with the same calls that you made.

// 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());

Running this example prints:

method1 [!Message1 {
  text: hello
}
]
method2 [!Message2 {
  number: 234
}
]
0
Domenico Schettini Filho On

Nice @PeterLawrey has a different way to build the processor. I mean in your example you print the objects I want populate the two different types of objects. I don't find a way until now using the methods in the same listener to do it.