fix lifecycle startup/stop ordering problem with discovery module and make druid able to load local extensions

This commit is contained in:
fjy 2013-09-24 14:20:56 -07:00
parent 15843c3978
commit be5bb7f2eb
3 changed files with 59 additions and 27 deletions

View File

@ -59,7 +59,7 @@ import java.util.concurrent.ThreadFactory;
/** /**
* The DiscoveryModule allows for the registration of Keys of DruidNode objects, which it intends to be * The DiscoveryModule allows for the registration of Keys of DruidNode objects, which it intends to be
* automatically announced at the end of the lifecycle start. * automatically announced at the end of the lifecycle start.
* * <p/>
* In order for this to work a ServiceAnnouncer instance *must* be injected and instantiated first. * In order for this to work a ServiceAnnouncer instance *must* be injected and instantiated first.
* This can often be achieved by registering ServiceAnnouncer.class with the LifecycleModule. * This can often be achieved by registering ServiceAnnouncer.class with the LifecycleModule.
*/ */
@ -69,19 +69,25 @@ public class DiscoveryModule implements Module
/** /**
* Requests that the un-annotated DruidNode instance be injected and published as part of the lifecycle. * Requests that the un-annotated DruidNode instance be injected and published as part of the lifecycle.
* * <p/>
* That is, this module will announce the DruidNode instance returned by * That is, this module will announce the DruidNode instance returned by
* injector.getInstance(Key.get(DruidNode.class)) automatically. * injector.getInstance(Key.get(DruidNode.class)) automatically.
* Announcement will happen in the LAST stage of the Lifecycle * Announcement will happen in the LAST stage of the Lifecycle
*/ */
public static void registerDefault(Binder binder) public static void registerDefault(Binder binder)
{ {
registerKey(binder, Key.get(new TypeLiteral<DruidNode>(){})); registerKey(
binder, Key.get(
new TypeLiteral<DruidNode>()
{
}
)
);
} }
/** /**
* Requests that the annotated DruidNode instance be injected and published as part of the lifecycle. * Requests that the annotated DruidNode instance be injected and published as part of the lifecycle.
* * <p/>
* That is, this module will announce the DruidNode instance returned by * That is, this module will announce the DruidNode instance returned by
* injector.getInstance(Key.get(DruidNode.class, annotation)) automatically. * injector.getInstance(Key.get(DruidNode.class, annotation)) automatically.
* Announcement will happen in the LAST stage of the Lifecycle * Announcement will happen in the LAST stage of the Lifecycle
@ -90,12 +96,18 @@ public class DiscoveryModule implements Module
*/ */
public static void register(Binder binder, Annotation annotation) public static void register(Binder binder, Annotation annotation)
{ {
registerKey(binder, Key.get(new TypeLiteral<DruidNode>(){}, annotation)); registerKey(
binder, Key.get(
new TypeLiteral<DruidNode>()
{
}, annotation
)
);
} }
/** /**
* Requests that the annotated DruidNode instance be injected and published as part of the lifecycle. * Requests that the annotated DruidNode instance be injected and published as part of the lifecycle.
* * <p/>
* That is, this module will announce the DruidNode instance returned by * That is, this module will announce the DruidNode instance returned by
* injector.getInstance(Key.get(DruidNode.class, annotation)) automatically. * injector.getInstance(Key.get(DruidNode.class, annotation)) automatically.
* Announcement will happen in the LAST stage of the Lifecycle * Announcement will happen in the LAST stage of the Lifecycle
@ -104,12 +116,18 @@ public class DiscoveryModule implements Module
*/ */
public static void register(Binder binder, Class<? extends Annotation> annotation) public static void register(Binder binder, Class<? extends Annotation> annotation)
{ {
registerKey(binder, Key.get(new TypeLiteral<DruidNode>(){}, annotation)); registerKey(
binder, Key.get(
new TypeLiteral<DruidNode>()
{
}, annotation
)
);
} }
/** /**
* Requests that the keyed DruidNode instance be injected and published as part of the lifecycle. * Requests that the keyed DruidNode instance be injected and published as part of the lifecycle.
* * <p/>
* That is, this module will announce the DruidNode instance returned by * That is, this module will announce the DruidNode instance returned by
* injector.getInstance(Key.get(DruidNode.class, annotation)) automatically. * injector.getInstance(Key.get(DruidNode.class, annotation)) automatically.
* Announcement will happen in the LAST stage of the Lifecycle * Announcement will happen in the LAST stage of the Lifecycle
@ -137,7 +155,9 @@ public class DiscoveryModule implements Module
.asEagerSingleton(); .asEagerSingleton();
} }
@Provides @LazySingleton @Named(NAME) @Provides
@LazySingleton
@Named(NAME)
public CuratorServiceAnnouncer getServiceAnnouncer( public CuratorServiceAnnouncer getServiceAnnouncer(
final CuratorServiceAnnouncer announcer, final CuratorServiceAnnouncer announcer,
final Injector injector, final Injector injector,
@ -181,7 +201,8 @@ public class DiscoveryModule implements Module
return announcer; return announcer;
} }
@Provides @LazySingleton @Provides
@LazySingleton
public ServiceDiscovery<Void> getServiceDiscovery( public ServiceDiscovery<Void> getServiceDiscovery(
CuratorFramework curator, CuratorFramework curator,
CuratorDiscoveryConfig config, CuratorDiscoveryConfig config,
@ -217,14 +238,14 @@ public class DiscoveryModule implements Module
throw Throwables.propagate(e); throw Throwables.propagate(e);
} }
} }
}, }
Lifecycle.Stage.LAST
); );
return serviceDiscovery; return serviceDiscovery;
} }
@Provides @LazySingleton @Provides
@LazySingleton
public ServerDiscoveryFactory getServerDiscoveryFactory( public ServerDiscoveryFactory getServerDiscoveryFactory(
ServiceDiscovery<Void> serviceDiscovery ServiceDiscovery<Void> serviceDiscovery
) )

View File

@ -29,6 +29,10 @@ import java.util.List;
*/ */
public class ExtensionsConfig public class ExtensionsConfig
{ {
@JsonProperty
@NotNull
private boolean searchCurrentClassloader = true;
@JsonProperty @JsonProperty
@NotNull @NotNull
private List<String> coordinates = ImmutableList.of(); private List<String> coordinates = ImmutableList.of();
@ -44,6 +48,11 @@ public class ExtensionsConfig
"https://metamx.artifactoryonline.com/metamx/pub-libs-releases-local" "https://metamx.artifactoryonline.com/metamx/pub-libs-releases-local"
); );
public boolean searchCurrentClassloader()
{
return searchCurrentClassloader;
}
public List<String> getCoordinates() public List<String> getCoordinates()
{ {
return coordinates; return coordinates;

View File

@ -139,14 +139,13 @@ public class
for (Artifact artifact : artifacts) { for (Artifact artifact : artifacts) {
if (!exclusions.contains(artifact.getGroupId())) { if (!exclusions.contains(artifact.getGroupId())) {
urls.add(artifact.getFile().toURI().toURL()); urls.add(artifact.getFile().toURI().toURL());
} } else {
else {
log.error("Skipped Artifact[%s]", artifact); log.error("Skipped Artifact[%s]", artifact);
} }
} }
for (URL url : urls) { for (URL url : urls) {
log.error("Added URL[%s]", url); log.info("Added URL[%s]", url);
} }
loader = new URLClassLoader(urls.toArray(new URL[urls.size()]), Initialization.class.getClassLoader()); loader = new URLClassLoader(urls.toArray(new URL[urls.size()]), Initialization.class.getClassLoader());
@ -165,6 +164,13 @@ public class
} }
} }
if (config.searchCurrentClassloader()) {
for (T module : ServiceLoader.load(clazz, Initialization.class.getClassLoader())) {
log.info("Adding local module[%s]", module.getClass());
retVal.add(module);
}
}
return retVal; return retVal;
} }
@ -243,7 +249,8 @@ public class
private final ObjectMapper smileMapper; private final ObjectMapper smileMapper;
private final List<Module> modules; private final List<Module> modules;
public ModuleList(Injector baseInjector) { public ModuleList(Injector baseInjector)
{
this.baseInjector = baseInjector; this.baseInjector = baseInjector;
this.jsonMapper = baseInjector.getInstance(Key.get(ObjectMapper.class, Json.class)); this.jsonMapper = baseInjector.getInstance(Key.get(ObjectMapper.class, Json.class));
this.smileMapper = baseInjector.getInstance(Key.get(ObjectMapper.class, Smile.class)); this.smileMapper = baseInjector.getInstance(Key.get(ObjectMapper.class, Smile.class));
@ -260,24 +267,19 @@ public class
if (input instanceof DruidModule) { if (input instanceof DruidModule) {
baseInjector.injectMembers(input); baseInjector.injectMembers(input);
modules.add(registerJacksonModules(((DruidModule) input))); modules.add(registerJacksonModules(((DruidModule) input)));
} } else if (input instanceof Module) {
else if (input instanceof Module) {
baseInjector.injectMembers(input); baseInjector.injectMembers(input);
modules.add((Module) input); modules.add((Module) input);
} } else if (input instanceof Class) {
else if (input instanceof Class) {
if (DruidModule.class.isAssignableFrom((Class) input)) { if (DruidModule.class.isAssignableFrom((Class) input)) {
modules.add(registerJacksonModules(baseInjector.getInstance((Class<? extends DruidModule>) input))); modules.add(registerJacksonModules(baseInjector.getInstance((Class<? extends DruidModule>) input)));
} } else if (Module.class.isAssignableFrom((Class) input)) {
else if (Module.class.isAssignableFrom((Class) input)) {
modules.add(baseInjector.getInstance((Class<? extends Module>) input)); modules.add(baseInjector.getInstance((Class<? extends Module>) input));
return; return;
} } else {
else {
throw new ISE("Class[%s] does not implement %s", input.getClass(), Module.class); throw new ISE("Class[%s] does not implement %s", input.getClass(), Module.class);
} }
} } else {
else {
throw new ISE("Unknown module type[%s]", input.getClass()); throw new ISE("Unknown module type[%s]", input.getClass());
} }
} }