|
99 | 99 | %% we are using file:pread/3 which leaves the file |
100 | 100 | %% position undetermined. |
101 | 101 | read_segment = undefined :: undefined | non_neg_integer(), |
102 | | - read_fd = undefined :: undefined | file:fd() |
| 102 | + read_fd = undefined :: undefined | file:fd(), |
| 103 | + |
| 104 | + %% Time at which the most recent buffer flush was done, |
| 105 | + %% or the most recent segment delete. This is used to skip |
| 106 | + %% the periodic flush when a flush was done recently, or |
| 107 | + %% when the current write file was recently deleted (to |
| 108 | + %% avoid {error,eacces} issues on Windows for files in |
| 109 | + %% "DELETE PENDING" state). |
| 110 | + last_disk_write = erlang:monotonic_time(millisecond) |
103 | 111 | }). |
104 | 112 |
|
105 | 113 | -type state() :: #qs{}. |
@@ -184,9 +192,15 @@ get_write_offset(Segment, Size, State = #qs{ write_segment = undefined }) -> |
184 | 192 |
|
185 | 193 | -spec sync(State) -> State when State::state(). |
186 | 194 |
|
187 | | -sync(State) -> |
| 195 | +sync(State=#qs{ last_disk_write = LastDiskWrite }) -> |
188 | 196 | ?DEBUG("~0p", [State]), |
189 | | - flush_buffer(State, fun(_) -> ok end). |
| 197 | + case erlang:monotonic_time(millisecond) of |
| 198 | + %% Half the sync interval in rabbitmq_amqqueue_process. |
| 199 | + Now when Now > LastDiskWrite + 100 -> |
| 200 | + flush_buffer(State, fun(_) -> ok end); |
| 201 | + _ -> |
| 202 | + State |
| 203 | + end. |
190 | 204 |
|
191 | 205 | maybe_flush_buffer(State = #qs{ write_buffer_size = WriteBufferSize }) -> |
192 | 206 | case WriteBufferSize >= max_cache_size() of |
@@ -227,7 +241,8 @@ flush_buffer(State0 = #qs{ write_buffer = WriteBuffer }, FsyncFun) -> |
227 | 241 | %% Finally we move the write_buffer to the cache. |
228 | 242 | State#qs{ write_buffer = #{}, |
229 | 243 | write_buffer_size = 0, |
230 | | - cache = WriteBuffer }. |
| 244 | + cache = WriteBuffer, |
| 245 | + last_disk_write = erlang:monotonic_time(millisecond) }. |
231 | 246 |
|
232 | 247 | flush_buffer_build(WriteBuffer = [{FirstSeqId, {Offset, _, _}}|_], |
233 | 248 | CheckCRC32, SegmentEntryCount) -> |
@@ -548,7 +563,8 @@ delete_segments(Segments, State0 = #qs{ write_buffer = WriteBuffer0, |
548 | 563 | end |
549 | 564 | end, {#{}, WriteBufferSize0}, WriteBuffer0), |
550 | 565 | State#qs{ write_buffer = WriteBuffer, |
551 | | - write_buffer_size = WriteBufferSize }. |
| 566 | + write_buffer_size = WriteBufferSize, |
| 567 | + last_disk_write = erlang:monotonic_time(millisecond) }. |
552 | 568 |
|
553 | 569 | %% ---- |
554 | 570 | %% |
|
0 commit comments