package com.netflix.governator;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Preconditions;
import com.netflix.governator.spi.LifecycleListener;
/**
* Wrapper for any LifecycleListener to provide this following functionality
* 1. Logging of events as INFO
* 2. Swallow any event handler exceptions during shutdown
*/
final class SafeLifecycleListener extends WeakReference<LifecycleListener> implements LifecycleListener {
private static final Logger LOG = LoggerFactory.getLogger(SafeLifecycleListener.class);
private final int delegateHash;
private final String asString;
public static SafeLifecycleListener wrap(LifecycleListener listener) {
Preconditions.checkNotNull(listener, "listener argument must be non-null");
return new SafeLifecycleListener(listener, null);
}
public static SafeLifecycleListener wrap(LifecycleListener listener, ReferenceQueue<LifecycleListener> refQueue) {
Preconditions.checkNotNull(listener, "listener argument must be non-null");
return new SafeLifecycleListener(listener, refQueue);
}
private SafeLifecycleListener(LifecycleListener delegate, ReferenceQueue<LifecycleListener> refQueue) {
super(delegate, refQueue);
this.delegateHash = delegate.hashCode();
this.asString = "SafeLifecycleListener@" + System.identityHashCode(this) + " [" + delegate.toString() + "]";
}
@Override
public void onStarted() {
LifecycleListener delegate = get();
if (delegate != null) {
LOG.info("Starting '{}'", delegate);
delegate.onStarted();
}
}
@Override
public void onStopped(Throwable t) {
LifecycleListener delegate = get();
if (delegate != null) {
if (t != null) {
LOG.info("Stopping '{}' due to '{}@{}'", delegate, t.getClass().getSimpleName(), System.identityHashCode(t));
}
else {
LOG.info("Stopping '{}'", delegate);
}
try {
delegate.onStopped(t);
}
catch (Exception e) {
LOG.info("onStopped failed for {}", delegate, e);
}
}
}
@Override
public String toString() {
return asString;
}
@Override
public int hashCode() {
return delegateHash;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
LifecycleListener delegate = get();
if (delegate != null) {
LifecycleListener otherDelegate = ((SafeLifecycleListener)obj).get();
return delegate == otherDelegate || delegate.equals(otherDelegate);
}
else {
return false;
}
}
}