Class: Datadog::CRubyBuffer
Overview
Buffer that stores objects, has a maximum size, and can be safely used concurrently with CRuby.
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.
This implementation allocates less memory and is faster than ThreadSafeBuffer.
Direct Known Subclasses
Constant Summary collapse
- FIXNUM_MAX =
A very large number to allow us to effectively drop all items when invoking
slice!(i, FIXNUM_MAX)
. (1 << 62) - 1
Instance Method Summary collapse
-
#replace!(item) ⇒ Object
Add a new
trace
in the local queue.
Methods inherited from Buffer
#close, #closed?, #concat, #empty?, #initialize, #length, #pop, #push
Constructor Details
This class inherits a constructor from Datadog::Buffer
Instance Method Details
#replace!(item) ⇒ Object
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.
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/ddtrace/buffer.rb', line 204 def replace!(item) # Ensure buffer stays within +max_size+ items. # This can happen when there's concurrent modification # between a call the check in `full?` and the `add!` call in # `full? ? replace!(item) : add!(item)`. # # We can still have `@items.size > @max_size` for a short period of # time, but we will always try to correct it here. # # `slice!` is performed before `delete_at` & `<<` to avoid always # removing the item that was just inserted. # # DEV: `slice!` with two integer arguments is ~10% faster than # `slice!` with a {Range} argument. @items.slice!(@max_size, FIXNUM_MAX) # We should replace a random trace with the new one replace_index = rand(@max_size) @items[replace_index] = item end |