Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix a bug that BufferChunkOverflowError cause a whole data loss
In the previous version, if BufferChunkOverflowError occurs, whole data is not sent because of raised exception. For example, incoming partial data exceeds chunk_limit_size, "message a" and "message b" is lost. message a\n longer.....message data exceeds chunk_limit_size\n message b\n It is not appropriate because the problem exists only a partial split data. In this commit, when BufferChunkOverflowError is detected in write_step_by_step, collect errors and propagate it to write method scope. By this way, a valid partial split is processed and not lost. Here is the micro benchmark result: It seems that it has slightly performance drawbacks, but all 'split' data is processed correctly without thrown away it when BufferChunkOverflowError occurs, thus it is not so critical. Before: Calculating ------------------------------------- no BufferChunkOverflowError 115.161k (±13.5%) i/s - 1.078M in 9.705579s raise BufferChunkOverflowError in every 100 calls 957.400 (±33.0%) i/s - 7.500k in 9.994991s Comparison: no BufferChunkOverflowError: 115160.5 i/s raise BufferChunkOverflowError in every 100 calls: 957.4 i/s - 120.28x (± 0.00) slower After: Calculating ------------------------------------- no BufferChunkOverflowError 114.962k (±13.4%) i/s - 1.080M in 9.724037s raise BufferChunkOverflowError in every 100 calls 907.511 (±32.1%) i/s - 7.081k in 10.003371s Comparison: no BufferChunkOverflowError: 114961.7 i/s raise BufferChunkOverflowError in every 100 calls: 907.5 i/s - 126.68x (± 0.00) slower Here is the micro benchmark test case: test '#write BufferChunkOverflowError micro benchmark' do require 'benchmark/ips' es = Fluent::ArrayEventStream.new([ [event_time('2016-04-11 16:00:02 +0000'), {"message" => "x"}] ]) large = Fluent::ArrayEventStream.new([ [event_time('2016-04-11 16:00:02 +0000'), {"message" => "x" * 1_280_000}] ]) Benchmark.ips do |x| x.config(:time => 10, :warmup => 0) x.report("no BufferChunkOverflowError") do @p.write({@dm0 => es}, format: @Format) end x.report("raise BufferChunkOverflowError in every 100 calls") do |n| n.times do |i| if i % 100 == 0 assert_raise Fluent::Plugin::Buffer::BufferChunkOverflowError do @p.write({@dm0 => large}, format: @Format) end else @p.write({@dm0 => es}, format: @Format) end end end x.compare! end end Signed-off-by: Kentaro Hayashi <[email protected]>
- Loading branch information