2017-08-07 44 views
1

以下代碼在第20次迭代的第二個assert語句上失敗 - 注意我只是重新創建了導致問題的代碼;計數不相關,而是寫入的字節數是。當'padToCacheAlign'== true時,Chronicle-Queue消息長度更改問題

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; 
     } 
    } 

問題似乎是在填充被添加到所述消息緩存它對準64個字節SingleChronicleQueueExcerpts類。我沒有預料到必須將自己的消息長度添加到我的寫入中,但是如果編年史隊列沒有將它自己的頭部填充到高速緩存行邊界,這似乎是不可避免的。

在此先感謝

回答

0

這是試圖解決的問題是,CAS操作不跨越高速緩存行實際上是原子!在ARM上,它只是獲得一個SIGBUS,但在x64上它只能運行99.999%的時間。

這是我們在客戶使用該格式後發現的,因此我們最終完成了這項工作。下一個主要版本應該解決這個問題。 我建議在開始時添加一個停止位編碼長度,它只會是一兩個字節。

+0

是否有一個原因,你沒有填充文件頭爲64字節,以避免'虛假共享'緩存線問題? –

+0

@big_cotton這會爲每封郵件平均添加32個字節。考慮到更新的唯一競爭值是隊列的最後一個消息頭,使用更多的高速緩存行會減慢隊列的速度(因爲它必須爲小消息寫入更多的數據) –

+0

啊 - 好了。非常感謝彼得。 –