diff --git a/extensions-core/lookups-cached-global/src/main/java/io/druid/query/lookup/NamespaceLookupExtractorFactory.java b/extensions-core/lookups-cached-global/src/main/java/io/druid/query/lookup/NamespaceLookupExtractorFactory.java index 54badfcde0e..14b1dab8fcb 100644 --- a/extensions-core/lookups-cached-global/src/main/java/io/druid/query/lookup/NamespaceLookupExtractorFactory.java +++ b/extensions-core/lookups-cached-global/src/main/java/io/druid/query/lookup/NamespaceLookupExtractorFactory.java @@ -232,4 +232,10 @@ public class NamespaceLookupExtractorFactory implements LookupExtractorFactory readLock.unlock(); } } + + @VisibleForTesting + CacheScheduler getCacheScheduler() + { + return cacheScheduler; + } } diff --git a/extensions-core/lookups-cached-global/src/main/java/io/druid/server/lookup/namespace/cache/CacheScheduler.java b/extensions-core/lookups-cached-global/src/main/java/io/druid/server/lookup/namespace/cache/CacheScheduler.java index a33346f0db4..bc323d781cb 100644 --- a/extensions-core/lookups-cached-global/src/main/java/io/druid/server/lookup/namespace/cache/CacheScheduler.java +++ b/extensions-core/lookups-cached-global/src/main/java/io/druid/server/lookup/namespace/cache/CacheScheduler.java @@ -24,6 +24,7 @@ import com.google.common.base.Throwables; import com.google.inject.Inject; import com.metamx.emitter.service.ServiceEmitter; import com.metamx.emitter.service.ServiceMetricEvent; +import io.druid.guice.LazySingleton; import io.druid.java.util.common.ISE; import io.druid.java.util.common.logger.Logger; import io.druid.query.lookup.namespace.ExtractionNamespace; @@ -60,6 +61,7 @@ import java.util.concurrent.atomic.AtomicReference; * entry.close(); // close the last VersionedCache and unschedule future updates * } */ +@LazySingleton public final class CacheScheduler { private static final Logger log = new Logger(CacheScheduler.class); diff --git a/extensions-core/lookups-cached-global/src/test/java/io/druid/query/lookup/NamespaceLookupExtractorFactoryTest.java b/extensions-core/lookups-cached-global/src/test/java/io/druid/query/lookup/NamespaceLookupExtractorFactoryTest.java index 5af474830aa..3858e488d42 100644 --- a/extensions-core/lookups-cached-global/src/test/java/io/druid/query/lookup/NamespaceLookupExtractorFactoryTest.java +++ b/extensions-core/lookups-cached-global/src/test/java/io/druid/query/lookup/NamespaceLookupExtractorFactoryTest.java @@ -31,7 +31,6 @@ import com.google.inject.Binder; import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.Module; - import io.druid.guice.GuiceInjectors; import io.druid.guice.JsonConfigProvider; import io.druid.guice.annotations.Json; @@ -42,8 +41,8 @@ import io.druid.java.util.common.ISE; import io.druid.query.lookup.namespace.ExtractionNamespace; import io.druid.query.lookup.namespace.URIExtractionNamespace; import io.druid.server.DruidNode; -import io.druid.server.lookup.namespace.cache.NamespaceExtractionCacheManager; import io.druid.server.lookup.namespace.cache.CacheScheduler; +import io.druid.server.lookup.namespace.cache.NamespaceExtractionCacheManager; import org.easymock.EasyMock; import org.easymock.IExpectationSetters; import org.joda.time.Period; @@ -440,21 +439,7 @@ public class NamespaceLookupExtractorFactoryTest @Test public void testSerDe() throws Exception { - final Injector injector = Initialization.makeInjectorWithModules( - GuiceInjectors.makeStartupInjector(), - ImmutableList.of( - new Module() - { - @Override - public void configure(Binder binder) - { - JsonConfigProvider.bindInstance( - binder, Key.get(DruidNode.class, Self.class), new DruidNode("test-inject", null, null) - ); - } - } - ) - ); + final Injector injector = makeInjector(); final ObjectMapper mapper = injector.getInstance(Key.get(ObjectMapper.class, Json.class)); mapper.registerSubtypes(NamespaceLookupExtractorFactory.class); final String str = "{ \"type\": \"cachedNamespace\", \"extractionNamespace\": { \"type\": \"uri\", \"uriPrefix\": \"s3://bucket/prefix/\", \"fileRegex\": \"foo.*\\\\.gz\", \"namespaceParseSpec\": { \"format\": \"customJson\", \"keyFieldName\": \"someKey\", \"valueFieldName\": \"someVal\" }, \"pollPeriod\": \"PT5M\" } } }"; @@ -484,21 +469,7 @@ public class NamespaceLookupExtractorFactoryTest @Test public void testSimpleIntrospectionHandler() throws Exception { - final Injector injector = Initialization.makeInjectorWithModules( - GuiceInjectors.makeStartupInjector(), - ImmutableList.of( - new Module() - { - @Override - public void configure(Binder binder) - { - JsonConfigProvider.bindInstance( - binder, Key.get(DruidNode.class, Self.class), new DruidNode("test-inject", null, null) - ); - } - } - ) - ); + final Injector injector = makeInjector(); final ObjectMapper mapper = injector.getInstance(Key.get(ObjectMapper.class, Json.class)); mapper.registerSubtypes(NamespaceLookupExtractorFactory.class); final String str = "{ \"type\": \"cachedNamespace\", \"extractionNamespace\": { \"type\": \"staticMap\", \"map\": {\"foo\":\"bar\"} }, \"firstCacheTimeout\":10000 }"; @@ -524,6 +495,40 @@ public class NamespaceLookupExtractorFactoryTest } } + @Test + public void testSingletonCacheScheduler() throws Exception + { + final Injector injector = makeInjector(); + final ObjectMapper mapper = injector.getInstance(Key.get(ObjectMapper.class, Json.class)); + mapper.registerSubtypes(NamespaceLookupExtractorFactory.class); + final String str1 = "{ \"type\": \"cachedNamespace\", \"extractionNamespace\": { \"type\": \"staticMap\", \"map\": {\"foo\":\"bar\"} }, \"firstCacheTimeout\":10000 }"; + final NamespaceLookupExtractorFactory factory1 = + (NamespaceLookupExtractorFactory) mapper.readValue(str1, LookupExtractorFactory.class); + final String str2 = "{ \"type\": \"cachedNamespace\", \"extractionNamespace\": { \"type\": \"uri\", \"uriPrefix\": \"s3://bucket/prefix/\", \"fileRegex\": \"foo.*\\\\.gz\", \"namespaceParseSpec\": { \"format\": \"customJson\", \"keyFieldName\": \"someKey\", \"valueFieldName\": \"someVal\" }, \"pollPeriod\": \"PT5M\" } } }"; + final NamespaceLookupExtractorFactory factory2 = + (NamespaceLookupExtractorFactory) mapper.readValue(str2, LookupExtractorFactory.class); + Assert.assertTrue(factory1.getCacheScheduler() == factory2.getCacheScheduler()); + } + + private Injector makeInjector() + { + return Initialization.makeInjectorWithModules( + GuiceInjectors.makeStartupInjector(), + ImmutableList.of( + new Module() + { + @Override + public void configure(Binder binder) + { + JsonConfigProvider.bindInstance( + binder, Key.get(DruidNode.class, Self.class), new DruidNode("test-inject", null, null) + ); + } + } + ) + ); + } + @Test public void testExceptionalIntrospectionHandler() throws Exception {