The easiest way to fix this code is to move the Collections.sort(values) to 
right after the zk.getChildren() and then use the following Comparator with 
Collections.sort() and Collections.binarySearch():

/* This Comparator defines an ordering such that the strings with
 * the lowest sequence numbers are first in sequence sorted order
 * followed by strings without sequence numbers in lexographical
 * order. This class assumes that a '-' preceeds the sequence
 * number. */
class SequenceComparator implements Comparator<String> {

    @Override
    public int compare(String o1, String o2) {
        int s1 = getSequence(o1);
        int s2 = getSequence(o2);
        if (s1 == -1 && s2 == -1) {
            return o1.compareTo(o2);
        }
        return s1 == -1 ? 1 : s2 == -1 ? -1 : s1 - s2 ? : -1;
    }

    /* Returns the sequence suffix of s. This method assumes that
     * the sequence number is prefixed with a '-'. */
    private int getSequence(String s) {
        int i = s.lastIndexOf('-');
        if (i != -1) {
            try {
                return Integer.parseInt(s.substring(i+1));
            // If an exception occurred we misdetected a sequence suffix,
            // so return -1.
            } catch(NumberFormatException e) {
            } catch(ArrayIndexOutOfBoundsException e) {
            }
        }
        return -1;
    }
}

ben

On Thursday 10 July 2008 22:20:06 Avinash Lakshman wrote:
> Hi
>
> I am trying to elect leader among 50 nodes. There is always one odd guy who
> seems to think that someone else distinct from what some other nodes see as
> leader. Could someone please tell me what is wrong with the following code
> for leader election:
>
> public void electLeader()
>         {
>             ZooKeeper zk = StorageService.instance().getZooKeeperHandle();
>             String path = "/Leader";
>             try
>             {
>                 String createPath = path +
> "/L-";
>                 LeaderElector.createLock_.lock();
>                 while( true )
>                 {
>                     /* Get all znodes under the Leader znode */
>                     List<String> values = zk.getChildren(path, false);
>                     /*
>                      * Get the first znode and if it is the
>                      * pathCreated created above then the data
>                      * in that znode is the leader's identity.
>                     */
>                     if ( leader_ == null )
>                     {
>                         leader_ = new AtomicReference<EndPoint>(
> EndPoint.fromBytes( zk.getData(path + "/" + values.get(0), false, null) )
> ); }
>                     else
>                     {
>                         leader_.set( EndPoint.fromBytes( zk.getData(path +
> "/" + values .get(0), false, null) ) );
>                         /* Disseminate the state as to who the leader is.
> */ onLeaderElection();
>                     }
>                     logger_.debug("Elected leader is " + leader_ + " @
> znode " + ( path + "/" + values.get(0) ) );
>                     Collections.sort(values);
>                     /* We need only the last portion of this znode */
>                     String[] peices = pathCreated_.split("/");
>                     int index = Collections.binarySearch(values,
> peices[peices.length - 1]);
>                     if ( index > 0 )
>                     {
>                         String pathToCheck = path + "/" + values.get(index
> - 1);
>                         Stat stat = zk.exists(pathToCheck, true);
>                         if ( stat != null )
>                         {
>                             logger_.debug("Awaiting my turn ...");
>                             condition_.await();
>                             logger_.debug("Checking to see if leader is
> around ...");
>                         }
>                     }
>                     else
>                     {
>                         break;
>                     }
>                 }
>             }
>             catch ( InterruptedException ex )
>             {
>                 logger_.warn(LogUtil.throwableToString(ex));
>             }
>             catch ( KeeperException ex )
>             {
>                 logger_.warn(LogUtil.throwableToString(ex));
>             }
>             finally
>             {
>                 LeaderElector.createLock_.unlock();
>             }
>         }
>     }
>
> Thanks
> Avinash



-------------------------------------------------------------------------
Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW!
Studies have shown that voting for your favorite open source project,
along with a healthy diet, reduces your potential for chronic lameness
and boredom. Vote Now at http://www.sourceforge.net/community/cca08
_______________________________________________
Zookeeper-user mailing list
Zookeeper-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/zookeeper-user

Reply via email to