Chronicle Queue - readDocument().isPresent() returning false when values are present

777 views Asked by At

I have modified the basic code here [github]https://github.com/OpenHFT/Chronicle-Queue/blob/master/docs/How_it_works.adoc

Basically I am shooting chronicle queue some of the same Marshallable-ized objects. I included some print statements to show what is going on.


import java.io.IOException;
import java.nio.file.Files;

import net.openhft.chronicle.queue.ExcerptAppender;
import net.openhft.chronicle.queue.ExcerptTailer;
import net.openhft.chronicle.queue.impl.single.SingleChronicleQueue;
import net.openhft.chronicle.queue.impl.single.SingleChronicleQueueBuilder;
import net.openhft.chronicle.wire.Marshallable;


public class App {

    static class MyObject implements Marshallable {
        String name;
        int age;

        @Override
        public String toString() {
            //return "";
            return Marshallable.$toString(this);
        }
    }

    public static void main(String[] args) throws IOException {

        // will write the .cq4 file to working directory
        SingleChronicleQueue queue = SingleChronicleQueueBuilder.builder().path(Files
                .createTempDirectory("queue").toFile()).build();
        ExcerptAppender appender = queue.acquireAppender();
        ExcerptTailer tailer = queue.createTailer();

        MyObject me = new MyObject();
        me.name = "rob";
        me.age = 40;

        System.out.println("1. Tailer is Present =  " + tailer.readingDocument().isPresent() + ", Tailer Current Index = " + tailer.index() + ", End = " + queue.createTailer().toEnd().index());
        // write 'MyObject' to the queue
        appender.writeDocument(me);
        appender.writeDocument(me);
        appender.writeDocument(me);
        appender.writeDocument(me);
        System.out.println("2. Tailer is Present =  " + tailer.readingDocument().isPresent() + ", Tailer Current Index = " + tailer.index() + ", End = " + queue.createTailer().toEnd().index());
        // read 'MyObject' from the queue
        MyObject result = new MyObject();
        tailer.readDocument(result);


        System.out.println("3. Tailer is Present =  " + tailer.readingDocument().isPresent() + ", Tailer Current Index = " + tailer.index() + ", End = " + queue.createTailer().toEnd().index());
        System.out.println(result);



        try {
            Thread.sleep(500);
        } catch (Exception e){
            System.out.println(e);
        }
        System.out.println("Tailer is Present =  " + tailer.readingDocument().isPresent() + ", Tailer Current Index = " + tailer.index() + ", End = " + queue.createTailer().toEnd().index());

    }
}

output

1. Tailer is Present =  false, Tailer Current Index = 0, End = 0
2. Tailer is Present =  true, Tailer Current Index = 78129750081536, End = 78129750081540
3. Tailer is Present =  false, Tailer Current Index = 78129750081536, End = 78129750081540
!chron.App$MyObject {
  name: !!null "",
  age: 0
}

Tailer is Present =  false, Tailer Current Index = 78129750081536, End = 78129750081540

So from my understanding... I have created a single static object. I have fed it to chronicle queue a total of four times, all of them the same object. You can see that chronicle queue has a total of four objects in it. Ending index - Starting Index.

The trailer.readingDocument().isPresent() only can see the first object that was created. after that it returns false...

If there are objects in the queue, then why is readingDocument().isPresent() returning false? Also why is the object returning null?

edit - version implementation 'net.openhft:chronicle-queue:5.17.25'

2

There are 2 answers

0
Dmitry Pisklov On BEST ANSWER

I rewrote your example with tryWithResources and it works. The problem in your code is that each call tailer.readingDocument().isPresent() is actually moving the pointer to the last read entry.

static class MyObject extends SelfDescribingMarshallable {
    String name;
    int age;
}

public static void main(String[] args) throws IOException {

    // will write the .cq4 file to working directory
    SingleChronicleQueue queue = SingleChronicleQueueBuilder.builder().path(Files.createTempDirectory("queue").toFile()).build();
    ExcerptAppender appender = queue.acquireAppender();
    ExcerptTailer tailer = queue.createTailer();

    MyObject me = new MyObject();
    me.name = "rob";
    me.age = 40;

    System.out.println("1. Tailer is Present =  " + tailer.readingDocument().isPresent() + ", Tailer Current Index = " + tailer.index() + ", End = " + queue.createTailer().toEnd().index());
    // write 'MyObject' to the queue
    try (final DocumentContext dc = appender.writingDocument()) {
        me.writeMarshallable(dc.wire());
    }
    try (final DocumentContext dc = appender.writingDocument()) {
        me.writeMarshallable(dc.wire());
    }
    try (final DocumentContext dc = appender.writingDocument()) {
        me.writeMarshallable(dc.wire());
    }
    try (final DocumentContext dc = appender.writingDocument()) {
        me.writeMarshallable(dc.wire());
    }
    try (final DocumentContext dc = tailer.readingDocument()) {
        System.out.println("2. Tailer is Present =  " + dc.isPresent() + ", Tailer Current Index = " + dc.index() + ", End = " + queue.createTailer().toEnd().index());
        if (dc.isPresent()) {
            MyObject result = new MyObject();
            result.readMarshallable(dc.wire());
            System.err.println(result);
        }
    }

    try (final DocumentContext dc = tailer.readingDocument()) {
        System.out.println("3. Tailer is Present =  " + dc.isPresent() + ", Tailer Current Index = " + dc.index() + ", End = " + queue.createTailer().toEnd().index());
        if (dc.isPresent()) {
            MyObject result = new MyObject();
            result.readMarshallable(dc.wire());
            System.err.println(result);
        }
    }

    try (final DocumentContext dc = tailer.readingDocument()) {
        System.out.println("4. Tailer is Present =  " + dc.isPresent() + ", Tailer Current Index = " + dc.index() + ", End = " + queue.createTailer().toEnd().index());
    }



    try {
        Thread.sleep(500);
    } catch (Exception e){
        System.out.println(e);
    }
    System.out.println("Tailer is Present =  " + tailer.readingDocument().isPresent() + ", Tailer Current Index = " + tailer.index() + ", End = " + queue.createTailer().toEnd().index());

}
1
Rob Austin On

try using it with a try-with-resources block, like this:

try (DocumentContext context = tailer.readingDocument()) {
 if (context.isPresent()) {
  // do something
 }
 int myIndex = context.index
}

for example

try (final DocumentContext dc = appender.writingDocument()) {
    dc.wire().write().text(“your text data“);
    System.out.println("your data was store to index="+ dc.index());
}

and

try (DocumentContext context = tailer.readingDocument()) {
   String youText = context.wire().read().text();
}