Проблема с изменением длины сообщения Chronicle-Queue, когда 'padToCacheAlign' == true

Следующий код дает сбой во втором утверждении утверждения на 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 байтам. Я не ожидал, что мне придется добавлять свои собственные длины сообщений к моим записям, но этого не избежать, если хроника-очередь не дополняет свой собственный заголовок к границе строки кэша.

заранее спасибо


person big_cotton    schedule 07.08.2017    source источник


Ответы (1)


Проблема, которую это пытается обойти, заключается в том, что операции CAS на самом деле не являются атомарными по строкам кэша! На ARM он просто получает SIGBUS, но на x64 он работает в 99,999% случаев.

Это было обнаружено нами после того, как формат стал использоваться клиентами, поэтому мы решили этот обходной путь. В следующей основной версии это должно быть исправлено. Я предлагаю добавить длину закодированного стопового бита в начало, которая будет составлять всего один или два байта.

person Peter Lawrey    schedule 08.08.2017
comment
Есть ли причина, по которой вы не дополняете заголовок документа до 64 байтов, чтобы избежать проблемы со строкой кэша «ложного совместного использования»? - person big_cotton; 08.08.2017
comment
@big_cotton это добавит в среднем 32 байта к каждому сообщению. Учитывая, что единственным обновленным спорным значением является заголовок последнего сообщения в очереди, использование большего количества строк кэша замедлит очередь (поскольку для небольших сообщений необходимо записать больше данных esp). - person Peter Lawrey; 09.08.2017