Skip to content

Commit

Permalink
Deprecated @WarmUp. @WarmUp will now behave exactly like @PostConstruct.
Browse files Browse the repository at this point in the history
  • Loading branch information
elandau committed May 19, 2016
1 parent d83f11f commit 079a512
Show file tree
Hide file tree
Showing 19 changed files with 164 additions and 1,454 deletions.
Expand Up @@ -22,12 +22,17 @@
import java.lang.annotation.Target;

/**
* Marks a method as a warm up method. Governator will execute warm up methods
* in parallel when the com.netflix.governator.lifecycle.LifecycleManager is started.
* @deprecated 2016-05-19 This class is being deprecated in favor of using {@literal @}PostConstruct
* or running initialization code in the constructor. While {@literal @}WarmUp did promise to help
* with parallel initialization of singletons it resulted in excessive complexity and invalidated DI
* expectations that a class is fully initialized by the time it is injected. WarmUp methods are
* now treated exactly like PostConstruct and are therefore guaranteed to have been executed by the
* time an object is injected.
*/
@Documented
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Deprecated
public @interface WarmUp
{
}
Expand Up @@ -16,37 +16,23 @@

package com.netflix.governator.guice;

import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicReference;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Sets;
import com.google.inject.AbstractModule;
import com.google.inject.ConfigurationException;
import com.google.inject.TypeLiteral;
import com.google.inject.matcher.Matchers;
import com.google.inject.spi.Dependency;
import com.google.inject.spi.InjectionListener;
import com.google.inject.spi.InjectionPoint;
import com.google.inject.spi.TypeEncounter;
import com.google.inject.spi.TypeListener;
import com.netflix.governator.annotations.WarmUp;
import com.netflix.governator.lifecycle.LifecycleListener;
import com.netflix.governator.lifecycle.LifecycleManager;
import com.netflix.governator.lifecycle.LifecycleMethods;
import com.netflix.governator.lifecycle.warmup.DAGManager;

class InternalLifecycleModule extends AbstractModule {
// this really serves as a Set purpose.
// put dummy boolean as Map value.
// value is really not important here.
private final CopyOnWriteArraySet<Dependency<?>> seen = new CopyOnWriteArraySet<Dependency<?>>();

private final LoadingCache<Class<?>, LifecycleMethods> lifecycleMethods = CacheBuilder
.newBuilder()
.softValues()
Expand Down Expand Up @@ -92,10 +78,6 @@ private <T> void processInjectedObject(T obj, TypeLiteral<T> type){
Class<?> clazz = obj.getClass();
LifecycleMethods methods = getLifecycleMethods(clazz);

if ( warmUpIsInDag(clazz, type) ) {
addDependencies(manager, obj, type, methods);
}

if ( methods.hasLifecycleAnnotations() ) {
try {
manager.add(obj, methods);
Expand All @@ -107,84 +89,6 @@ private <T> void processInjectedObject(T obj, TypeLiteral<T> type){
}
}

private void addDependencies(LifecycleManager manager, Object obj, TypeLiteral<?> type, LifecycleMethods methods) {
DAGManager dagManager = manager.getDAGManager();
dagManager.addObjectMapping(type, obj, methods);

applyInjectionPoint(getConstructorInjectionPoint(type), dagManager, type);
for ( InjectionPoint injectionPoint : getMethodInjectionPoints(type) )
{
applyInjectionPoint(injectionPoint, dagManager, type);
}
}

private boolean warmUpIsInDag(Class<?> clazz, TypeLiteral<?> type) {
LifecycleMethods methods = getLifecycleMethods(clazz);
if ( methods.methodsFor(WarmUp.class).size() > 0 ) {
return true;
}

if ( warmUpIsInDag(getConstructorInjectionPoint(type)) ) {
return true;
}

for ( InjectionPoint injectionPoint : getMethodInjectionPoints(type) ) {
if ( warmUpIsInDag(injectionPoint) ) {
return true;
}
}

return false;
}

private boolean warmUpIsInDag(InjectionPoint injectionPoint)
{
if ( injectionPoint == null ) {
return false;
}

List<Dependency<?>> dependencies = injectionPoint.getDependencies();
for ( Dependency<?> dependency : dependencies ) {
if (seen.add(dependency)) {
if ( warmUpIsInDag(dependency.getKey().getTypeLiteral().getRawType(), dependency.getKey().getTypeLiteral()) ) {
return true;
}
}
}
return false;
}

private Set<InjectionPoint> getMethodInjectionPoints(TypeLiteral<?> type) {
try {
return InjectionPoint.forInstanceMethodsAndFields(type);
}
catch ( NullPointerException e ) {
// ignore - unfortunately this is happening inside of Guice
}
catch ( ConfigurationException e ) {
// ignore
}
return Sets.newHashSet();
}

private InjectionPoint getConstructorInjectionPoint(TypeLiteral<?> type) {
try {
return InjectionPoint.forConstructorOf(type);
}
catch ( ConfigurationException e ) {
// ignore
}
return null;
}

private void applyInjectionPoint(InjectionPoint injectionPoint, DAGManager dagManager, TypeLiteral<?> type) {
if ( injectionPoint != null ) {
for ( Dependency<?> dependency : injectionPoint.getDependencies() ) {
dagManager.addDependency(type, dependency.getKey().getTypeLiteral());
}
}
}

private LifecycleMethods getLifecycleMethods(Class<?> clazz) {
try {
return lifecycleMethods.get(clazz);
Expand Down
Expand Up @@ -16,14 +16,13 @@

package com.netflix.governator.lifecycle;

import java.util.Arrays;
import java.util.Collection;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.inject.TypeLiteral;

import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.TimeUnit;

/**
* Wrapper listener that forwards to the provided listener only when the obj is in one of the
* specified base packages.
Expand Down Expand Up @@ -93,20 +92,4 @@ private boolean isInPackages(Class type)
}
return false;
}

// @Override
// public <T> void objectInjected(TypeLiteral<T> type, T obj, long duration, TimeUnit units) {
// if ( isInPackages(obj) )
// {
// listener.objectInjected(type, obj, duration, units);
// }
// }
//
// @Override
// public <T> void objectInjecting(TypeLiteral<T> type) {
// if ( isInPackages(type.getRawType()) )
// {
// listener.objectInjecting(type);
// }
// }
}
Expand Up @@ -16,6 +16,35 @@

package com.netflix.governator.lifecycle;

import java.beans.Introspector;
import java.io.Closeable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.annotation.Resources;
import javax.naming.NamingException;
import javax.validation.ConstraintViolation;
import javax.validation.Path;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
Expand All @@ -27,39 +56,11 @@
import com.google.inject.Injector;
import com.google.inject.Singleton;
import com.netflix.governator.annotations.PreConfiguration;
import com.netflix.governator.annotations.WarmUp;
import com.netflix.governator.configuration.ConfigurationColumnWriter;
import com.netflix.governator.configuration.ConfigurationDocumentation;
import com.netflix.governator.configuration.ConfigurationMapper;
import com.netflix.governator.configuration.ConfigurationProvider;
import com.netflix.governator.lifecycle.warmup.DAGManager;
import com.netflix.governator.lifecycle.warmup.WarmUpDriver;
import com.netflix.governator.lifecycle.warmup.WarmUpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.annotation.Resources;
import javax.naming.NamingException;
import javax.validation.ConstraintViolation;
import javax.validation.Path;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.beans.Introspector;
import java.io.Closeable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
* Main instance management container
Expand All @@ -77,9 +78,6 @@ public class LifecycleManager implements Closeable
private final Collection<LifecycleListener> listeners;
private final Collection<ResourceLocator> resourceLocators;
private final ValidatorFactory factory;
private final DAGManager dagManager = new DAGManager();
private final PostStartArguments postStartArguments;
private final AtomicReference<WarmUpSession> postStartWarmUpSession = new AtomicReference<WarmUpSession>(null);
private final Injector injector;
private com.netflix.governator.LifecycleManager newLifecycleManager;

Expand All @@ -102,7 +100,6 @@ public LifecycleManager(LifecycleManagerArguments arguments, Injector injector)
listeners = ImmutableSet.copyOf(arguments.getLifecycleListeners());
resourceLocators = ImmutableSet.copyOf(arguments.getResourceLocators());
factory = Validation.buildDefaultValidatorFactory();
postStartArguments = arguments.getPostStartArguments();
configurationDocumentation = arguments.getConfigurationDocumentation();
configurationProvider = arguments.getConfigurationProvider();
}
Expand Down Expand Up @@ -208,23 +205,20 @@ public void start() throws Exception
* @return true if warm up methods successfully executed, false if the time elapses
* @throws Exception errors
*/
@Deprecated
public boolean start(long maxWait, TimeUnit unit) throws Exception
{
Preconditions.checkState(state.compareAndSet(State.LATENT, State.STARTING), "Already started");

validate();

long maxMs = (unit != null) ? unit.toMillis(maxWait) : Long.MAX_VALUE;
WarmUpSession warmUpSession = new WarmUpSession(getWarmUpDriver(), dagManager);
boolean success = warmUpSession.doImmediate(maxMs);

new ConfigurationColumnWriter(configurationDocumentation).output(log);
if (newLifecycleManager != null) {
newLifecycleManager.notifyStarted();
}
state.set(State.STARTED);

return success;
return true;
}

@Override
Expand Down Expand Up @@ -289,14 +283,6 @@ public void validate(Object obj) throws ValidationException
}
}

/**
* @return the internal DAG manager
*/
public DAGManager getDAGManager()
{
return dagManager;
}

private void setState(Object obj, LifecycleState state)
{
objectStates.put(new StateKey(obj), state);
Expand Down Expand Up @@ -348,6 +334,13 @@ private void startInstance(Object obj, LifecycleMethods methods) throws Exceptio
log.debug(String.format("\t%s()", postConstruct.getName()));
postConstruct.invoke(obj);
}

for ( Method postConstruct : methods.methodsFor(WarmUp.class) )
{
log.info("**** @WarmUp is now deprecated. Please replace @WarmUp with @PostConstruct ****");
log.debug(String.format("\t%s()", postConstruct.getName()));
postConstruct.invoke(obj);
}

Collection<Method> preDestroyMethods = methods.methodsFor(PreDestroy.class);
if ( preDestroyMethods.size() > 0 )
Expand Down Expand Up @@ -581,50 +574,6 @@ public String apply(Path.Node node)
private void initializeObjectPostStart(Object obj) throws ValidationException
{
validate(obj);

postStartWarmUpSession.compareAndSet(null, new WarmUpSession(getWarmUpDriver(), dagManager));
WarmUpSession session = postStartWarmUpSession.get();
session.doInBackground();
}

private WarmUpDriver getWarmUpDriver()
{
return new WarmUpDriver()
{
@Override
public void setPreWarmUpState()
{
for ( StateKey key : objectStates.keySet() )
{
objectStates.put(key, LifecycleState.PRE_WARMING_UP);
}
}

@Override
public void setPostWarmUpState()
{
Iterator<LifecycleState> iterator = objectStates.values().iterator();
while ( iterator.hasNext() )
{
if ( iterator.next() != LifecycleState.ERROR )
{
iterator.remove();
}
}
}

@Override
public PostStartArguments getPostStartArguments()
{
return postStartArguments;
}

@Override
public void setState(Object obj, LifecycleState state)
{
LifecycleManager.this.setState(obj, state);
}
};
}

private enum State
Expand Down

0 comments on commit 079a512

Please sign in to comment.