Chronicle-Queue 'padToCacheAlign' == true 时消息长度更改问题

Chronicle-Queue message length changes issue when 'padToCacheAlign' == true

以下代码在第 20 次迭代的第二个 assert 语句上失败 - 请注意,我只是重新创建导致问题的代码;计数不相关,而是写入的字节数。

    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 class 中,其中填充被添加到消息中以缓存对齐到 64 字节。我没有预料到必须将自己的消息长度添加到我的写入中,但如果 chronicle-queue 没有将它自己的 header 填充到缓存行边界,这似乎是不可避免的。

提前致谢

它试图解决的问题是 CAS 操作实际上并不是跨缓存行的原子操作!!在 ARM 上它只得到一个 SIGBUS 但在 x64 上它只在 99.999% 的时间内工作。

这是我们在客户使用该格式后发现的,因此我们最终解决了这个问题。下一个主要版本应该会解决这个问题。 我建议在开头添加一个停止位编码长度,这只会是一个或两个字节。