All Downloads are FREE. Search and download functionalities are using the official Maven repository.

netflix.ocelli.Instance Maven / Gradle / Ivy

There is a newer version: 0.1.0-rc.2
Show newest version
package netflix.ocelli;

import rx.Observable;
import rx.functions.Func1;
import rx.observables.GroupedObservable;

/**
 * Representation of a single instance within a pool.  Up/Down state is managed via
 * an Observable where emitting true means the member is active and false
 * means the member is not active (possible due to failure detection).  onCompleted
 * indicates that the PoolMember has been removed.
 * 
 * @author elandau
 *
 * @param 
 */
public class Instance extends Observable {
    private final T value;
    
    private static class KeyedInstance {
        private final K key;
        private final Instance member;

        KeyedInstance(K key, Instance member) {
            this.key = key;
            this.member = member;
        }
    }
    
    /**
     * Partition Members into multiple partitions based on a partition function.  
     * It's possible for a member to exist in multiple partitions.  Each partition
     * is a GroupedObservable of members for that partition alone.  This stream can 
     * be fed into a load balancer.
     * 
     * Partitions are useful in the following use cases.
     * 
     * 1. Hosts are grouped into VIPs where each VIP subset can service a certain subset of 
     *    requests.  In the example below API's provided by vip1 can be serviced by Hosts 1,2,3
     *    whereas API's provied by vip2 can only be serviced by hosts 2 and 3.
     *    
     *  VIP : F(Host) -> O(vip)   Multiple vips
     *  
     *       Host1, Host2, Host3
     *       Host2, Host3
     *      
     * 2. Shard or hash aware clients using consistent hashing (ex. Cassandra) or sharding (ex. EvCache)
     *    will opt to send traffic only to nodes that can own the data.  The partitioner function
     *    will return the tokenRangeId or shardId for each host.  Note that for replication factor of 1
     *    each shard will contain only 1 host while for higher replication factors each shard will contain
     *    multiple hosts (equal to the number of shards) and that these hosts will overlap.
     *  
     *       Host1, Host2
     *       Host2, Host3
     *       Host3, Host4
     *       Host4, Host5
     *
     * @author elandau
     *
     * @param    Client type
     * @param    The partition key
     */
    public static  Transformer, GroupedObservable>> partitionBy(final Func1> partitioner) {
        return new Transformer, GroupedObservable>>() {
            @Override
            public Observable>> call(final Observable> o) {
                return o
                    .flatMap(new Func1, Observable>>() {
                        @Override
                        public Observable> call(final Instance member) {
                            return partitioner
                                    .call(member.getValue())
                                    .map(new Func1>() {
                                        @Override
                                        public KeyedInstance call(K key) {
                                            return new KeyedInstance(key, member);
                                        }
                                    });
                        }
                    })
                    .groupBy(
                        new Func1, K>() {
                            @Override
                            public K call(KeyedInstance t1) {
                                return t1.key;
                            }
                        }, 
                        new Func1, Instance>() {
                            @Override
                            public Instance call(KeyedInstance t1) {
                                return t1.member;
                            }
                        });
            }
        };
    }

    public Instance(T value, OnSubscribe state) {
        super(state);
        this.value = value;
    }
    
    public T getValue() {
        return this.value;
    }
    
    public String toString() {
        return "Member[" + value + "]";
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy