Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

round robin scheduling java iterators

I have a list of hosts in an array which represnt the servers available to do a particular job. Currently I simply iterate thru the list looking and establish comms with a host to check its not busy. If not I will send a job to it. This approach tends to mean that the first host in the list tends to get hot constanly with the load not balanced properly with the rest of the available hosts.

in pseudocode ..

for (Host h : hosts) {

    //checkstatus
    if status == job accepted break;

}

I'd like to balance this load properly between the hosts i.e first time host one is used 2nd time the method is used host 2. Just wondering that the most elegant solution to this is ??

Thanks W

like image 646
wmitchell Avatar asked Jan 11 '10 12:01

wmitchell


3 Answers

Google collections has a utility method Iterators.cycle(Iterable<T> iterable) that does what you want.

like image 183
Buhb Avatar answered Nov 01 '22 02:11

Buhb


You can create a new kind of Iterable that provides round-robin iteration:

public class RoundRobin<T> implements Iterable<T> {
      private List<T> coll;

      public RoundRobin(List<T> coll) { this.coll = coll; }

      public Iterator<T> iterator() { 
         return new Iterator<T>() {
            private int index = 0;

            @Override
            public boolean hasNext() {
                return true;
            }

            @Override
            public T next() {
                T res = coll.get(index);
                index = (index + 1) % coll.size();
                return res;
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException();
            }

        };
    }
}

You need to define your hosts as RoundRobin<Host>.

[FIXED based on Mirko's comment]

like image 21
Itay Maman Avatar answered Nov 01 '22 03:11

Itay Maman


If the list is mutable and the cost of editing it is negligible compared to I/O with the hosts, you can just rotate it:

List<String> list = Arrays.asList("one", "two", "three");
Collections.rotate(list, -1);
System.out.println(list);
like image 9
McDowell Avatar answered Nov 01 '22 03:11

McDowell