com.yahoo.pasc.paxos.Barrier.java Source code

Java tutorial

Introduction

Here is the source code for com.yahoo.pasc.paxos.Barrier.java

Source

/**
 * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. See accompanying LICENSE file.
 */

package com.yahoo.pasc.paxos;

import java.io.IOException;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.KeeperException.Code;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.yahoo.pasc.paxos.client.PaxosClientHandler;

public class Barrier implements Watcher {
    private static final Logger LOG = LoggerFactory.getLogger(Barrier.class);

    private int size;
    private String name;
    private ZooKeeper zk;
    private Object mutex;
    private String root;

    /**
     * Barrier constructor
     * 
     * @param address
     * @param root
     * @param size
     * @throws IOException
     * @throws KeeperException
     */
    public Barrier(ZooKeeper zk, String root, String name, int size) throws KeeperException, IOException {
        this.zk = zk;
        this.mutex = new Object();
        this.root = root;
        this.size = size;
        this.name = name;

        try {
            zk.create(root, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        } catch (KeeperException e) {
            if (e.code().equals(Code.NODEEXISTS)) {
                //ignore
            } else {
                LOG.error("Keeper exception when instantiating barrier.", e);
            }
        } catch (InterruptedException e) {
            LOG.error("Interrupted exception", e);
        }
    }

    /**
     * Join barrier
     * 
     * @return
     * @throws KeeperException
     * @throws InterruptedException
     */

    public boolean enter() throws KeeperException, InterruptedException {
        zk.create(root + "/" + name, null, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
        int children = zk.getChildren(root, false).size();
        if (children >= size) {
            try {
                zk.create(root + "/start", null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            } catch (KeeperException e) {
                if (e.code().equals(Code.NODEEXISTS)) {
                    return true;
                } else
                    throw e;
            }
            return true;
        }
        while (true) {
            synchronized (mutex) {
                Stat stat = zk.exists(root + "/start", this);
                if (stat != null) {
                    return true;
                }
                mutex.wait();
            }
        }
    }

    /**
     * Wait until all reach barrier
     * 
     * @return
     * @throws KeeperException
     * @throws InterruptedException
     */
    public boolean leave() throws KeeperException, InterruptedException {
        zk.delete(root + "/" + name, -1);
        while (true) {
            synchronized (mutex) {
                int children = zk.getChildren(root, this).size();
                if (children == 1) {
                    try {
                        zk.delete(root + "/start", -1);
                    } catch (KeeperException e) {
                        if (e.code().equals(Code.NONODE)) {
                            return true;
                        } else
                            throw e;
                    }
                } else if (children == 0) {
                    return true;
                } else {
                    mutex.wait();
                }
            }
        }
    }

    @Override
    public void process(org.apache.zookeeper.WatchedEvent event) {
        if (event.getType().equals(EventType.NodeChildrenChanged)
                || event.getType().equals(EventType.NodeCreated)) {
            synchronized (mutex) {
                mutex.notify();
            }
        }
    }

    public void close() throws InterruptedException {
        zk.close();
    }
}