以下代码在第20次迭代的第二个断言语句中失败 - 请注意我只是重新创建导致问题的代码;计数不相关,而是写入的字节数。
SingleChronicleQueue writer = SingleChronicleQueueBuilder.binary("/tmp/broken").build();
ExcerptAppender excerptAppender = writer.acquireAppender();
try(DocumentContext dc = excerptAppender.writingDocument())
{
dc.wire().bytes().writeSkip(36);
}
for(int i = 0; i < 20; i++)
{
try (DocumentContext dc = excerptAppender.writingDocument())
{
dc.wire().bytes().writeSkip(14);
}
}
SingleChronicleQueue reader = SingleChronicleQueueBuilder.binary("/tmp/broken").build();
ExcerptTailer tailer = reader.createTailer();
try(DocumentContext dc = tailer.readingDocument())
{
assert dc.isPresent() && dc.wire().bytes().readRemaining() == 36;
}
for(int i = 0; i < 20; i++)
{
try(DocumentContext dc = tailer.readingDocument())
{
//Fails on the 20th read .. with 16 bytes being returned
assert dc.isPresent() && dc.wire().bytes().readRemaining() == 14;
}
}
问题似乎出现在SingleChronicleQueueExcerpts类中,其中填充添加到消息以缓存以将其对齐到64字节。我没有预料到必须将自己的消息长度添加到我的写入中,但如果chronicle-queue没有将其自己的标头填充到高速缓存行边界,那么它似乎无法避免。
提前致谢
答案 0 :(得分:0)
这个试图解决的问题是CAS操作实际上不是跨缓存行的原子!!在ARM上它只获得一个SIGBUS,但在x64上它只有99.999%的时间工作。
这是我们在客户使用该格式后发现的,因此我们最终完成了这项工作。下一个主要版本应该解决这个问题。 我建议在开始时添加一个停止位编码长度,它只是一个或两个字节。