class Datadog::CRubyBuffer
Buffer
that stores objects, has a maximum size, and can be safely used concurrently with CRuby.
Under extreme concurrency scenarios, this class can exceed its max_size
by up to 4%.
Because singular Array
operations are thread-safe in CRuby, we can implement the trace buffer without an explicit lock, while making the compromise of allowing the buffer to go over its maximum limit under extreme circumstances.
On the following scenario:
-
4.5 million spans/second.
-
Pushed into a single
CRubyTraceBuffer
from 1000 threads.
The buffer can exceed its maximum size by no more than 4%.
This implementation allocates less memory and is faster than {Datadog::ThreadSafeBuffer}.
@see spec/ddtrace/benchmark/buffer_benchmark_spec.rb Buffer
benchmarks @see github.com/ruby-concurrency/concurrent-ruby/blob/c1114a0c6891d9634f019f1f9fe58dcae8658964/lib/concurrent-ruby/concurrent/array.rb#L23-L27
Public Instance Methods
Add a new “trace“ in the local queue. This method doesn't block the execution even if the buffer is full. In that case, a random trace is discarded.
# File lib/ddtrace/buffer.rb, line 200 def replace!(item) # we should replace a random trace with the new one replace_index = rand(@items.size) replaced_trace = @items.delete_at(replace_index) @items << item # We might have deleted an element right when the buffer # was drained, thus +replaced_trace+ will be +nil+. # In that case, nothing was replaced, and this method # performed a simple insertion into the buffer. replaced_trace end