netflix.ocelli.ListToInstance Maven / Gradle / Ivy
package netflix.ocelli;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import rx.Observable;
import rx.Observable.Transformer;
import rx.functions.Func1;
import rx.functions.Func2;
/**
* Utility class to convert a full list of load balancer members to an Observable
* by diffing the new list with the last list.
*
* @author elandau
*
* @param
* @param
*/
public class ListToInstance implements Transformer, Instance> {
private final Func1 keyFunc;
public ListToInstance(Func1 keyFunc) {
this.keyFunc = keyFunc;
}
public static class State {
final Map> members = new HashMap>();
List> newInstances = Collections.emptyList();
}
@Override
public Observable> call(Observable> o) {
return o.scan(new State(), new Func2, List, State>() {
@Override
public State call(State state, List instances) {
Map> toRemove = new HashMap>(state.members);
state.newInstances = new ArrayList>();
for (T ii : instances) {
toRemove.remove(keyFunc.call(ii));
if (!state.members.containsKey(keyFunc.call(ii))) {
MutableInstance member = MutableInstance.from(ii);
state.members.put(keyFunc.call(ii), member);
state.newInstances.add(member);
}
}
for (Entry> member : toRemove.entrySet()) {
state.members.remove(member.getKey());
member.getValue().close();
}
return state;
}
})
.concatMap(new Func1, Observable>>() {
@Override
public Observable> call(State state) {
return Observable.from(state.newInstances);
}
});
}
}