Chronicle Queue - readDocument(). IsPresent() возвращает false при наличии значений
Я изменил базовый код здесь [github]https://github.com/OpenHFT/Chronicle-Queue/blob/master/docs/How_it_works.adoc
В основном я снимаю в хронологическом порядке одни и те же Маршаллируемые объекты. Я включил несколько операторов печати, чтобы показать, что происходит.
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());
}
}
выход
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
Итак, насколько я понимаю... я создал один статический объект. Я загружал его в очередь хроник в общей сложности четыре раза, и все они были одним и тем же объектом. Вы можете видеть, что в очереди хроники всего четыре объекта. Конечный индекс - Начальный индекс.
Trailer.readingDocument(). IsPresent() может видеть только первый созданный объект. после этого возвращается false...
Если в очереди есть объекты, то почему readDocument (). IsPresent() возвращает false? Также почему объект возвращает ноль?
edit - реализация версии 'net.openhft:chronicle-queue:5.17.25'
2 ответа
Я переписал ваш пример с помощью tryWithResources, и он работает. Проблема в вашем коде заключается в том, что каждый вызов tailer.readingDocument(). IsPresent() фактически перемещает указатель на последнюю прочитанную запись.
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());
}
Попробуйте использовать его с блоком try-with-resources, например:
try (DocumentContext context = tailer.readingDocument()) {
if (context.isPresent()) {
// do something
}
int myIndex = context.index
}
например
try (final DocumentContext dc = appender.writingDocument()) {
dc.wire().write().text(“your text data“);
System.out.println("your data was store to index="+ dc.index());
}
а также
try (DocumentContext context = tailer.readingDocument()) {
String youText = context.wire().read().text();
}