Tidy up construction of the Guice Injectors#12816
Conversation
|
This pull request introduces 2 alerts when merging 7992d8a into 5772dfd - view on LGTM.com new alerts:
|
Builders for various module collections Revise the extensions loader Injector builders for server startup Move Hadoop init to indexer Clean up server node role filtering Calcite test injector builder
efd4bcc to
e631781
Compare
gianm
left a comment
There was a problem hiding this comment.
Looks like a nicer way of doing things.
| static { | ||
| EXTENSIONS_CONFIG = INJECTOR.getInstance(ExtensionsConfig.class); | ||
| } | ||
| // Note: static variables mean that this task cannot run in a shared JVM, |
There was a problem hiding this comment.
Is this because ExtensionsLoader isn't concurrency-safe?
As far as I can tell, the prior code was OK to use in a shared JVM: it was an Injector (which I think is concurrency-safe?) and and ExtensionsConfig (immutable; definitely fine).
There was a problem hiding this comment.
The issue here is more basic: static variables. If task A and task B both run in the Indexer, then they share a single copy of the static variable (unless the Indexer loads them in isolated class loaders.) By contrast, the ExtensionsLoader was converted from static variables to a Guice-injected singleton to avoid this issue. For ExtensionsLoader the only time two instances will appear in the same JVM is in tests, which used to have special code to undo the static variables between tests.
The HadoopTask approach seems more like a bug than a feature. A good enhancement would be to modify the HadoopTask to use Guice (and the ExtensionsLoader, perhaps modified for the Hadoop dependencies) to avoid the static variable issue.
There was a problem hiding this comment.
Yeah, the HadoopTask is done in a weird way. But I was asking if anything bad happens due to sharing the statics between different tasks. The comment makes it sound like something will break, but I can't tell what it is. If nothing will break, it'd be better to get rid of (or reword) the comment.
There was a problem hiding this comment.
Looking more closely, you may be right that this particular use is OK. There will be a single injector and set of extensions used by multiple tasks, which should be OK. Removed the comment.
| } | ||
|
|
||
| @Test | ||
| @Ignore("assumes record rates, to be fixed in separate PR") |
There was a problem hiding this comment.
What's the issue here? I don't understand the comment.
There was a problem hiding this comment.
Sorry, cryptic. This test failed repeatedly in this PR. Discussions with other engineers revealed that the test itself is flawed: it assumes the test duration. Someone else is fixing that. This temporary hack exists just so that this PR will build. I'll check if the required fix has been submitted yet, and if so, will remove this annotation.
There was a problem hiding this comment.
Ah, I see. Is there a GitHub issue for the flaky test? It'd be good to link that here so the comment makes more sense.
There was a problem hiding this comment.
Done. Sounds like #12852 will remove this test, so noted that here.
server/src/test/java/org/apache/druid/initialization/ServerInjectorBuilderTest.java
Outdated
Show resolved
Hide resolved
processing/src/main/java/org/apache/druid/guice/ExtensionsLoader.java
Outdated
Show resolved
Hide resolved
processing/src/main/java/org/apache/druid/guice/ExtensionsLoader.java
Outdated
Show resolved
Hide resolved
processing/src/main/java/org/apache/druid/guice/GuiceInjectors.java
Outdated
Show resolved
Hide resolved
server/src/main/java/org/apache/druid/initialization/Initialization.java
Show resolved
Hide resolved
server/src/main/java/org/apache/druid/initialization/ServerInjectorBuilder.java
Outdated
Show resolved
Hide resolved
|
@gianm, thanks much for the review! Address your comments. You pointed out a couple of tender spots in areas I avoided changing. Please take a look at the responses so we can figure out if we need to do anything more. The suggestion for the default implementation of |
I just wrote a few replies. When you have a chance to look at these I think this patch is good to go for me. |
See Issue #12815 for an overview of the goal of this PR. This PR provides the basic refactoring to allow a later PR to restructure the Calcite test setup which will in turn simply the proposed Druid planner test framework. This PR also lays the groundwork to simplify the complex, ad-hoc code which the "new ITs" use to set up tests.
Refactors Guice Injector Construction
See the above issue for an overview.
ExtensionsLoaderThe
Initializationclass currently performa a kitchen-sink set of tasks, one of which is to load extensions. That code was pulled out into a separate class:ExtensionsLoader. The previous code used global maps to hold extension information, and cobbled together a way to pass a config object into staticInitializationmethods.The new approach is that
ExtensionsLoaderis Guice-enabled: it is created by the startup injector and passed to the primary injector. Guice, then, manages the singleton for this class. Clients of the code now obtain anExtensionsLoaderfrom Guice.InitializationTestcases related to extensions moved into a newExtensionsLoaderTestclass.Hadoop Initialization
The
Initializationclass also holds a method,getHadoopDependencyFilesToLoad(), used only by Hadoop indexing tasks. This code moved to a newInitializationclass in the indexing module. The test cases moved to a new test class.InitializationDeprecationThe
Initializationclass is now virtually empty:The only functionality left in
InitializationismakeInjectorWithModules(), now marked as deprecated, to build an injector. However, this method adds all the server dependencies, which is not what is wanted for tests. Over time, tests will be refactored to build an injector with just the modules needed, and without server baggage. At that time, we'll drop themakeInjectorWithModules()method and thus theInitializationclass itself.GuiceInjectorsDeprecationSimilarly, the
GuiceInjectorsclass builds the startup injector. As tests shift to use the builders,GuiceInjectorscan disappear.CalciteTestsInjectorBuilderThe "Calcite tests" has an elaborate set of ad-hoc code in CalciteTests to hand-wire a set of mock objects. The planner test PR struggled to refactor the code to allow more flexibility. A key motivation of this clean-up is to provide a framework that uses Guice to construct the Calcite test environment.
In this PR, we define a CalciteTestsInjectorBuilder class to build the injector that was previously built in a static initializer. This class is just a proof-of-concept at present: it is useful by itself. The real goal is to gradually move the ad-hoc code that creates planner-related object in Calcite tests to use this new builder (or a variation.)
This PR has: