diff options
| author | Matthew Sackman <matthew@lshift.net> | 2009-08-22 18:23:04 +0100 |
|---|---|---|
| committer | Matthew Sackman <matthew@lshift.net> | 2009-08-22 18:23:04 +0100 |
| commit | cb4f27280ecc3c578b5098e4e8fb6e5c92e842a0 (patch) | |
| tree | f62c0e2bc2330b0b498f86e4cbb67fe924f63f1e /src | |
| parent | 08b05fae992823443d75fb8fd2eb1ddf88c4aeb3 (diff) | |
| download | rabbitmq-server-git-cb4f27280ecc3c578b5098e4e8fb6e5c92e842a0.tar.gz | |
Could repeatably read zeros.
With the handle position caching in, avoiding seeks opened a lovely opportunity for reading zeros. The read handle had read_ahead turned on, so even though the write handle was being sync'd correctly, the next read was reading cached data. Consequently, reading zeros instead of the real message.
This makes a valuable point which is that with read_ahead turned on, the seeks on every read, as was happening previously, were evicting the read_ahead cache, even if the seek was in effect a noop. Thus read_ahead, in combination with the seeks, made no performance gain.
Consequently, turning read_ahead off and only seeking when necessary is a performance gain, over (pointlessly) having read_ahead on and seeking every time. Turning read_ahead off also solves this reading zeros bug.
Finally, corrected some maths so that we now check to see if the sync offset is < the offset we will reach rather than <= the offset we read from. Because the offsets should only ever be on message boundaries, both will work, but the new version is more intuitively correct.
Diffstat (limited to 'src')
| -rw-r--r-- | src/rabbit_disk_queue.erl | 7 |
1 files changed, 3 insertions, 4 deletions
diff --git a/src/rabbit_disk_queue.erl b/src/rabbit_disk_queue.erl index d19469d682..344aff9181 100644 --- a/src/rabbit_disk_queue.erl +++ b/src/rabbit_disk_queue.erl @@ -761,18 +761,17 @@ get_read_handle(File, Offset, TotalSize, State = current_dirty = IsDirty, last_sync_offset = SyncOffset }) -> - State1 = if CurName =:= File andalso IsDirty andalso Offset >= SyncOffset -> + NewOffset = Offset + TotalSize + ?FILE_PACKING_ADJUSTMENT, + State1 = if CurName =:= File andalso IsDirty andalso NewOffset > SyncOffset -> sync_current_file_handle(State); true -> State end, Now = now(), - NewOffset = Offset + TotalSize + ?FILE_PACKING_ADJUSTMENT, {FileHdl, OldOffset, ReadHdls1, ReadHdlsAge1} = case dict:find(File, ReadHdls) of error -> {ok, Hdl} = file:open(form_filename(File), - [read, raw, binary, - read_ahead]), + [read, raw, binary]), case dict:size(ReadHdls) < ReadFileHandlesLimit of true -> {Hdl, 0, ReadHdls, ReadHdlsAge}; |
