WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
b14fb6b
Removes jctools usage for lock-free queues.
amarziali Nov 3, 2025
7ec0c8f
Refactor
amarziali Nov 4, 2025
bd10c81
Introduce varhandle based queues
amarziali Nov 4, 2025
161e053
Try to optimise more java 9+ implementation
amarziali Nov 4, 2025
89a7668
Try to optimise varhandle version further
amarziali Nov 5, 2025
7849d6b
Remove old java 8 implementation and reintroduce jctools for 1.8
amarziali Nov 5, 2025
0ac7bea
Use a better time wait poll
amarziali Nov 6, 2025
0eeda81
try to improve the fairness
amarziali Nov 6, 2025
117848f
Simplify and make more fair the spin wait
amarziali Nov 7, 2025
24b2fe6
Fix the wait condition
amarziali Nov 7, 2025
f1f2edd
Use getAndAdd for the offer fast path
amarziali Nov 7, 2025
b70ea33
Move to queue-utils
amarziali Nov 7, 2025
a521825
Revert "Use getAndAdd for the offer fast path"
amarziali Nov 7, 2025
1690cb9
let it inline
amarziali Nov 7, 2025
1b99e0a
Refine documentation
amarziali Nov 10, 2025
5fb87ae
Final updates
amarziali Nov 10, 2025
9ec4612
oups
amarziali Nov 10, 2025
1135f56
Update bench figures
amarziali Nov 10, 2025
62789f3
Use dedicated class hierarchy to ensure the padding is applied
amarziali Nov 17, 2025
933b2f9
Pad consumer and producer limits
amarziali Nov 17, 2025
69d9ed0
Pad elements in the buffer
amarziali Nov 17, 2025
a5039de
Change nextPowOfTwo
amarziali Nov 19, 2025
04ef492
Incorporate latest changes - make queues race free
amarziali Dec 4, 2025
9f062b9
adjust after rebase
amarziali Dec 5, 2025
fdb956e
Backport lookahead
amarziali Dec 8, 2025
462d956
Update bench
amarziali Dec 8, 2025
08badb2
Realign implementation with candidate upstream
amarziali Dec 8, 2025
8d20a42
Add junit based tests
amarziali Dec 8, 2025
d3143ce
update bench results
amarziali Dec 8, 2025
438a50b
Avoid allocating the double - remove unused methods
amarziali Dec 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions dd-java-agent/agent-llmobs/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ dependencies {
implementation project(':communication')
implementation project(':components:json')
implementation project(':internal-api')
implementation project(':utils:queue-utils')


testImplementation project(':dd-java-agent:testing')
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

import com.squareup.moshi.JsonAdapter;
import com.squareup.moshi.Moshi;
import datadog.common.queue.MessagePassingBlockingQueue;
import datadog.common.queue.Queues;
import datadog.communication.ddagent.DDAgentFeaturesDiscovery;
import datadog.communication.ddagent.SharedCommunicationObjects;
import datadog.communication.http.HttpRetryPolicy;
Expand All @@ -20,7 +22,6 @@
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import org.jctools.queues.MpscBlockingConsumerArrayQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -34,7 +35,7 @@ public class EvalProcessingWorker implements AutoCloseable {

private static final Logger log = LoggerFactory.getLogger(EvalProcessingWorker.class);

private final MpscBlockingConsumerArrayQueue<LLMObsEval> queue;
private final MessagePassingBlockingQueue<LLMObsEval> queue;
private final Thread serializerThread;

public EvalProcessingWorker(
Expand All @@ -43,7 +44,7 @@ public EvalProcessingWorker(
final TimeUnit timeUnit,
final SharedCommunicationObjects sco,
Config config) {
this.queue = new MpscBlockingConsumerArrayQueue<>(capacity);
this.queue = Queues.mpscBlockingConsumerArrayQueue(capacity);

boolean isAgentless = config.isLlmObsAgentlessEnabled();
if (isAgentless && (config.getApiKey() == null || config.getApiKey().isEmpty())) {
Expand Down Expand Up @@ -98,7 +99,7 @@ public static class EvalSerializingHandler implements Runnable {
private static final Logger log = LoggerFactory.getLogger(EvalSerializingHandler.class);
private static final int FLUSH_THRESHOLD = 50;

private final MpscBlockingConsumerArrayQueue<LLMObsEval> queue;
private final MessagePassingBlockingQueue<LLMObsEval> queue;
private final long ticksRequiredToFlush;
private long lastTicks;

Expand All @@ -111,7 +112,7 @@ public static class EvalSerializingHandler implements Runnable {
private final List<LLMObsEval> buffer = new ArrayList<>();

public EvalSerializingHandler(
final MpscBlockingConsumerArrayQueue<LLMObsEval> queue,
final MessagePassingBlockingQueue<LLMObsEval> queue,
final long flushInterval,
final TimeUnit timeUnit,
final HttpUrl submissionUrl,
Expand Down
3 changes: 3 additions & 0 deletions dd-java-agent/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,9 @@ dependencies {
sharedShadowInclude project(':utils:socket-utils'), {
transitive = false
}
sharedShadowInclude project(':utils:queue-utils'), {
transitive = false
}
sharedShadowInclude project(':utils:version-utils'), {
transitive = false
}
Expand Down
3 changes: 3 additions & 0 deletions dd-trace-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ dependencies {
implementation project(':components:json')
implementation project(':utils:container-utils')
implementation project(':utils:socket-utils')
implementation project(':utils:queue-utils')
// for span exception debugging
compileOnly project(':dd-java-agent:agent-debugger:debugger-bootstrap')

Expand All @@ -80,6 +81,8 @@ dependencies {

implementation group: 'com.google.re2j', name: 're2j', version: '1.7'

jmhImplementation(libs.jctools)

// We have autoservices defined in test subtree, looks like we need this to be able to properly rebuild this
testAnnotationProcessor libs.autoservice.processor
testCompileOnly libs.autoservice.annotation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Iterator;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
import org.jctools.queues.MessagePassingQueue;
import org.jctools.queues.MpscCompoundQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -22,8 +20,8 @@ final class Aggregator implements Runnable {

private static final Logger log = LoggerFactory.getLogger(Aggregator.class);

private final Queue<Batch> batchPool;
private final MpscCompoundQueue<InboxItem> inbox;
private final MessagePassingQueue<Batch> batchPool;
private final MessagePassingQueue<InboxItem> inbox;
private final LRUCache<MetricKey, AggregateMetric> aggregates;
private final ConcurrentMap<MetricKey, Batch> pending;
private final Set<MetricKey> commonKeys;
Expand All @@ -42,8 +40,8 @@ final class Aggregator implements Runnable {

Aggregator(
MetricWriter writer,
Queue<Batch> batchPool,
MpscCompoundQueue<InboxItem> inbox,
MessagePassingQueue<Batch> batchPool,
MessagePassingQueue<InboxItem> inbox,
ConcurrentMap<MetricKey, Batch> pending,
final Set<MetricKey> commonKeys,
int maxAggregates,
Expand All @@ -63,8 +61,8 @@ final class Aggregator implements Runnable {

Aggregator(
MetricWriter writer,
Queue<Batch> batchPool,
MpscCompoundQueue<InboxItem> inbox,
MessagePassingQueue<Batch> batchPool,
MessagePassingQueue<InboxItem> inbox,
ConcurrentMap<MetricKey, Batch> pending,
final Set<MetricKey> commonKeys,
int maxAggregates,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static java.util.Collections.unmodifiableSet;
import static java.util.concurrent.TimeUnit.SECONDS;

import datadog.common.queue.Queues;
import datadog.communication.ddagent.DDAgentFeaturesDiscovery;
import datadog.communication.ddagent.SharedCommunicationObjects;
import datadog.trace.api.Config;
Expand All @@ -39,16 +40,14 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import javax.annotation.Nonnull;
import org.jctools.queues.MpscCompoundQueue;
import org.jctools.queues.SpmcArrayQueue;
import org.jctools.queues.MessagePassingQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -90,11 +89,11 @@ public final class ConflatingMetricsAggregator implements MetricsAggregator, Eve
new HashSet<>(Arrays.asList(SPAN_KIND_CLIENT, SPAN_KIND_PRODUCER, SPAN_KIND_CONSUMER)));

private final Set<String> ignoredResources;
private final Queue<Batch> batchPool;
private final MessagePassingQueue<Batch> batchPool;
private final ConcurrentHashMap<MetricKey, Batch> pending;
private final ConcurrentHashMap<MetricKey, MetricKey> keys;
private final Thread thread;
private final MpscCompoundQueue<InboxItem> inbox;
private final MessagePassingQueue<InboxItem> inbox;
private final Sink sink;
private final Aggregator aggregator;
private final long reportingInterval;
Expand Down Expand Up @@ -177,8 +176,8 @@ public ConflatingMetricsAggregator(
long reportingInterval,
TimeUnit timeUnit) {
this.ignoredResources = ignoredResources;
this.inbox = new MpscCompoundQueue<>(queueSize);
this.batchPool = new SpmcArrayQueue<>(maxAggregates);
this.inbox = Queues.mpscArrayQueue(queueSize);
this.batchPool = Queues.spmcArrayQueue(maxAggregates);
this.pending = new ConcurrentHashMap<>(maxAggregates * 4 / 3);
this.keys = new ConcurrentHashMap<>();
this.features = features;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import static datadog.trace.common.metrics.EventListener.EventType.OK;
import static java.util.concurrent.TimeUnit.SECONDS;

import datadog.common.queue.Queues;
import datadog.trace.util.AgentTaskScheduler;
import java.io.IOException;
import java.nio.ByteBuffer;
Expand All @@ -23,7 +24,7 @@
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import org.jctools.queues.SpscArrayQueue;
import org.jctools.queues.MessagePassingQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -36,7 +37,7 @@ public final class OkHttpSink implements Sink, EventListener {
private final OkHttpClient client;
private final HttpUrl metricsUrl;
private final List<EventListener> listeners;
private final SpscArrayQueue<Request> enqueuedRequests = new SpscArrayQueue<>(10);
private final MessagePassingQueue<Request> enqueuedRequests = Queues.spscArrayQueue(16);
private final AtomicLong lastRequestTime = new AtomicLong();
private final AtomicLong asyncRequestCounter = new AtomicLong();
private final boolean bufferingEnabled;
Expand Down Expand Up @@ -157,9 +158,9 @@ private void handleFailure(okhttp3.Response response) throws IOException {

private static final class Sender implements AgentTaskScheduler.Task<OkHttpSink> {

private final SpscArrayQueue<Request> inbox;
private final MessagePassingQueue<Request> inbox;

private Sender(SpscArrayQueue<Request> inbox) {
private Sender(MessagePassingQueue<Request> inbox) {
this.inbox = inbox;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import static datadog.trace.util.AgentThreadFactory.newAgentThread;
import static java.util.concurrent.TimeUnit.MILLISECONDS;

import datadog.common.queue.MessagePassingBlockingQueue;
import datadog.common.queue.Queues;
import datadog.communication.ddagent.DroppingPolicy;
import datadog.trace.common.sampling.SingleSpanSampler;
import datadog.trace.core.DDSpan;
Expand All @@ -13,7 +15,6 @@
import java.util.List;
import java.util.Queue;
import org.jctools.queues.MessagePassingQueue;
import org.jctools.queues.MpscBlockingConsumerArrayQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -45,7 +46,7 @@ class DefaultSpanSamplingWorker implements SpanSamplingWorker {

private final Thread spanSamplingThread;
private final SamplingHandler samplingHandler;
private final MpscBlockingConsumerArrayQueue<Object> spanSamplingQueue;
private final MessagePassingBlockingQueue<Object> spanSamplingQueue;
private final Queue<Object> primaryQueue;
private final Queue<Object> secondaryQueue;
private final SingleSpanSampler singleSpanSampler;
Expand All @@ -62,7 +63,7 @@ protected DefaultSpanSamplingWorker(
DroppingPolicy droppingPolicy) {
this.samplingHandler = new SamplingHandler();
this.spanSamplingThread = newAgentThread(SPAN_SAMPLING_PROCESSOR, samplingHandler);
this.spanSamplingQueue = new MpscBlockingConsumerArrayQueue<>(capacity);
this.spanSamplingQueue = Queues.mpscBlockingConsumerArrayQueue(capacity);
this.primaryQueue = primaryQueue;
this.secondaryQueue = secondaryQueue;
this.singleSpanSampler = singleSpanSampler;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import static datadog.trace.util.AgentThreadFactory.newAgentThread;
import static java.util.concurrent.TimeUnit.MILLISECONDS;

import datadog.common.queue.MessagePassingBlockingQueue;
import datadog.common.queue.Queues;
import datadog.communication.ddagent.DroppingPolicy;
import datadog.trace.api.Config;
import datadog.trace.bootstrap.instrumentation.api.SpanPostProcessor;
Expand All @@ -20,7 +22,6 @@
import java.util.concurrent.TimeUnit;
import java.util.function.BooleanSupplier;
import org.jctools.queues.MessagePassingQueue;
import org.jctools.queues.MpscBlockingConsumerArrayQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -36,8 +37,8 @@ public class TraceProcessingWorker implements AutoCloseable {
private static final Logger log = LoggerFactory.getLogger(TraceProcessingWorker.class);

private final PrioritizationStrategy prioritizationStrategy;
private final MpscBlockingConsumerArrayQueue<Object> primaryQueue;
private final MpscBlockingConsumerArrayQueue<Object> secondaryQueue;
private final MessagePassingBlockingQueue<Object> primaryQueue;
private final MessagePassingBlockingQueue<Object> secondaryQueue;
private final TraceSerializingHandler serializingHandler;
private final Thread serializerThread;
private final int capacity;
Expand Down Expand Up @@ -121,23 +122,23 @@ public long getRemainingCapacity() {
return primaryQueue.remainingCapacity();
}

private static MpscBlockingConsumerArrayQueue<Object> createQueue(int capacity) {
return new MpscBlockingConsumerArrayQueue<>(capacity);
private static MessagePassingBlockingQueue<Object> createQueue(int capacity) {
return Queues.mpscBlockingConsumerArrayQueue(capacity);
}

public static class TraceSerializingHandler implements Runnable {

private final MpscBlockingConsumerArrayQueue<Object> primaryQueue;
private final MpscBlockingConsumerArrayQueue<Object> secondaryQueue;
private final MessagePassingBlockingQueue<Object> primaryQueue;
private final MessagePassingBlockingQueue<Object> secondaryQueue;
private final HealthMetrics healthMetrics;
private final long ticksRequiredToFlush;
private final boolean doTimeFlush;
private final PayloadDispatcher payloadDispatcher;
private long lastTicks;

public TraceSerializingHandler(
final MpscBlockingConsumerArrayQueue<Object> primaryQueue,
final MpscBlockingConsumerArrayQueue<Object> secondaryQueue,
final MessagePassingBlockingQueue<Object> primaryQueue,
final MessagePassingBlockingQueue<Object> secondaryQueue,
final HealthMetrics healthMetrics,
final PayloadDispatcher payloadDispatcher,
final long flushInterval,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import static datadog.trace.util.AgentThreadFactory.newAgentThread;
import static java.util.Comparator.comparingLong;

import datadog.common.queue.MessagePassingBlockingQueue;
import datadog.common.queue.Queues;
import datadog.communication.ddagent.SharedCommunicationObjects;
import datadog.trace.api.Config;
import datadog.trace.api.flare.TracerFlare;
Expand All @@ -21,7 +23,6 @@
import java.util.function.Predicate;
import java.util.zip.ZipOutputStream;
import org.jctools.queues.MessagePassingQueue;
import org.jctools.queues.MpscBlockingConsumerArrayQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -61,7 +62,7 @@ private static class DelayingPendingTraceBuffer extends PendingTraceBuffer {
private static final CommandElement DUMP_ELEMENT = new CommandElement();
private static final CommandElement STAND_IN_ELEMENT = new CommandElement();

private final MpscBlockingConsumerArrayQueue<Element> queue;
private final MessagePassingBlockingQueue<Element> queue;
private final Thread worker;
private final TimeSource timeSource;

Expand Down Expand Up @@ -292,7 +293,7 @@ public DelayingPendingTraceBuffer(
Config config,
SharedCommunicationObjects sharedCommunicationObjects,
HealthMetrics healthMetrics) {
this.queue = new MpscBlockingConsumerArrayQueue<>(bufferSize);
this.queue = Queues.mpscBlockingConsumerArrayQueue(bufferSize);
this.worker = newAgentThread(TRACE_MONITOR, new Worker());
this.timeSource = timeSource;
boolean runningSpansEnabled = config.isLongRunningTraceEnabled();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import static datadog.trace.util.AgentThreadFactory.THREAD_JOIN_TIMOUT_MS;
import static datadog.trace.util.AgentThreadFactory.newAgentThread;

import datadog.common.queue.Queues;
import datadog.communication.ddagent.DDAgentFeaturesDiscovery;
import datadog.communication.ddagent.SharedCommunicationObjects;
import datadog.context.propagation.Propagator;
Expand Down Expand Up @@ -38,7 +39,7 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import org.jctools.queues.MpscArrayQueue;
import org.jctools.queues.MessagePassingQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -53,7 +54,7 @@ public class DefaultDataStreamsMonitoring implements DataStreamsMonitoring, Even
new StatsPoint(DataStreamsTags.EMPTY, 0, 0, 0, 0, 0, 0, 0, null);

private final Map<Long, Map<String, StatsBucket>> timeToBucket = new HashMap<>();
private final MpscArrayQueue<InboxItem> inbox = new MpscArrayQueue<>(1024);
private final MessagePassingQueue<InboxItem> inbox = Queues.mpscArrayQueue(1024);
private final DatastreamsPayloadWriter payloadWriter;
private final DDAgentFeaturesDiscovery features;
private final TimeSource timeSource;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,9 @@ class SpanSamplingWorkerTest extends DDSpecification {
singleSpanSampler.setSamplingPriority(span7) >> true

when:
worker.getSpanSamplingQueue().offer([span1, span2, span3])
worker.getSpanSamplingQueue().offer([span4, span5])
worker.getSpanSamplingQueue().offer([span6, span7])
assert worker.getSpanSamplingQueue().offer([span1, span2, span3])
assert worker.getSpanSamplingQueue().offer([span4, span5])
assert worker.getSpanSamplingQueue().offer([span6, span7])

then:
primaryQueue.take() == [span1, span3]
Expand Down
1 change: 1 addition & 0 deletions gradle/dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ final class CachedData {
exclude(project(':utils:config-utils'))
exclude(project(':utils:container-utils'))
exclude(project(':utils:filesystem-utils'))
exclude(project(':utils:queue-utils'))
exclude(project(':utils:socket-utils'))
exclude(project(':utils:time-utils'))
exclude(project(':utils:version-utils'))
Expand Down
Loading