This is an automated email from the ASF dual-hosted git repository.
abhishekrb19 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git
The following commit(s) were added to refs/heads/master by this push:
new 5d84de19bf9 perf: materialize child emitters in ComposingEmitter to
avoid per-event Guice resolution (#19942)
5d84de19bf9 is described below
commit 5d84de19bf9a911f5d601b9f3b729ee27c04c30c
Author: Rushikesh Bankar <[email protected]>
AuthorDate: Wed Aug 12 22:56:24 2026 +0530
perf: materialize child emitters in ComposingEmitter to avoid per-event
Guice resolution (#19942)
Fixed lock contention on the metrics emit path when using the composing
emitter (druid.emitter=composing). Child emitters are now resolved once at
startup instead of on every emitted event, which previously caused significant
monitor contention on nodes emitting metrics at high volume.
---
.../server/emitter/ComposingEmitterModule.java | 18 ++++---------
.../initialization/ComposingEmitterModuleTest.java | 31 ++++++++++++++++++++++
2 files changed, 36 insertions(+), 13 deletions(-)
diff --git
a/server/src/main/java/org/apache/druid/server/emitter/ComposingEmitterModule.java
b/server/src/main/java/org/apache/druid/server/emitter/ComposingEmitterModule.java
index 254f86193a1..a830b7d6449 100644
---
a/server/src/main/java/org/apache/druid/server/emitter/ComposingEmitterModule.java
+++
b/server/src/main/java/org/apache/druid/server/emitter/ComposingEmitterModule.java
@@ -19,8 +19,7 @@
package org.apache.druid.server.emitter;
-import com.google.common.base.Function;
-import com.google.common.collect.Lists;
+import com.google.common.collect.ImmutableList;
import com.google.inject.Binder;
import com.google.inject.Injector;
import com.google.inject.Key;
@@ -55,17 +54,10 @@ public class ComposingEmitterModule implements DruidModule
{
log.info("Creating Composing Emitter with %s", config.getEmitters());
- List<Emitter> emitters = Lists.transform(
- config.getEmitters(),
- new Function<>()
- {
- @Override
- public Emitter apply(String s)
- {
- return injector.getInstance(Key.get(Emitter.class,
Names.named(s)));
- }
- }
- );
+ List<Emitter> emitters = config.getEmitters()
+ .stream()
+ .map(s ->
injector.getInstance(Key.get(Emitter.class, Names.named(s))))
+ .collect(ImmutableList.toImmutableList());
return new ComposingEmitter(emitters);
}
diff --git
a/server/src/test/java/org/apache/druid/initialization/ComposingEmitterModuleTest.java
b/server/src/test/java/org/apache/druid/initialization/ComposingEmitterModuleTest.java
index ab0a5eb9119..4f372b9bc6b 100644
---
a/server/src/test/java/org/apache/druid/initialization/ComposingEmitterModuleTest.java
+++
b/server/src/test/java/org/apache/druid/initialization/ComposingEmitterModuleTest.java
@@ -28,6 +28,7 @@ import com.google.inject.name.Names;
import org.apache.druid.guice.DruidGuiceExtensions;
import org.apache.druid.guice.LifecycleModule;
import org.apache.druid.java.util.emitter.core.Emitter;
+import org.apache.druid.java.util.emitter.core.Event;
import org.apache.druid.server.emitter.ComposingEmitterConfig;
import org.apache.druid.server.emitter.ComposingEmitterModule;
import org.easymock.EasyMock;
@@ -70,6 +71,36 @@ public class ComposingEmitterModuleTest
EasyMock.verify(config, emitter, injector);
}
+ @Test
+ public void testEmitDoesNotReResolveChildEmitters()
+ {
+ ComposingEmitterConfig config =
EasyMock.createMock(ComposingEmitterConfig.class);
+
EasyMock.expect(config.getEmitters()).andReturn(Collections.singletonList(testEmitterType)).anyTimes();
+
+ Event event = EasyMock.createNiceMock(Event.class);
+
+ Emitter child = EasyMock.createMock(Emitter.class);
+ child.start();
+ child.emit(event);
+ EasyMock.expectLastCall().times(3);
+ EasyMock.replay(child, event);
+
+ Injector injector = EasyMock.createMock(Injector.class);
+ // The child emitter must be resolved from the injector exactly once (at
construction), not once per emitted event.
+ EasyMock.expect(injector.getInstance(Key.get(Emitter.class,
Names.named(testEmitterType))))
+ .andReturn(child)
+ .once();
+ EasyMock.replay(config, injector);
+
+ Emitter composingEmitter = new ComposingEmitterModule().getEmitter(config,
injector);
+ composingEmitter.start();
+ composingEmitter.emit(event);
+ composingEmitter.emit(event);
+ composingEmitter.emit(event);
+
+ EasyMock.verify(config, injector, child);
+ }
+
@Test
public void testGetEmitterViaRealGuice()
{
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]