ch.usi.da.paxos.old.Proposer.java Source code

Java tutorial

Introduction

Here is the source code for ch.usi.da.paxos.old.Proposer.java

Source

package ch.usi.da.paxos.old;
/* 
 * Copyright (c) 2013 Universit della Svizzera italiana (USI)
 * 
 * This file is part of URingPaxos.
 *
 * URingPaxos is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * URingPaxos is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with URingPaxos.  If not, see <http://www.gnu.org/licenses/>.
 */

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;

import ch.usi.da.paxos.message.Value;
import ch.usi.da.paxos.storage.Promise;

/**
 * Name: Proposer<br>
 * Description: <br>
 * 
 * Creation date: Apr 1, 2012<br>
 * $Id$
 * 
 * @author Samuel Benz benz@geoid.ch
 */
public class Proposer implements Watcher {

    private final int threadCount = 5;

    /**
     * Server start time
     */
    public final long start_time = System.currentTimeMillis();

    private final int ID;

    private volatile boolean leader = false;

    private final ZooKeeper zoo;

    private final String path = "/paxos";

    private AtomicLong globalInstance = new AtomicLong();

    private final ExecutorService executer = Executors.newFixedThreadPool(threadCount);

    private final ExecutorService leader_sender = Executors.newFixedThreadPool(threadCount);

    private final ExecutorService reserver = Executors.newFixedThreadPool(1);

    private final ExecutorService leader_listener = Executors.newFixedThreadPool(1);

    private final BlockingQueue<Value> values = new LinkedBlockingQueue<Value>(500);

    private final BlockingQueue<Promise> promises = new LinkedBlockingQueue<Promise>(10);

    private volatile boolean perf_test = false;

    private final AtomicLong send_count = new AtomicLong(0);

    private final AtomicLong recv_count = new AtomicLong(0);

    private final AtomicLong recv_bytes = new AtomicLong(0);

    /**
     * Public constructor
     * 
     * @param id proposer id
     * @param config path to config file
     * @throws IOException 
     */
    public Proposer(int id, String config) throws IOException {
        this.ID = id;
        if (Configuration.getConfiguration().isEmpty()) {
            Configuration.read(config);
        }
        zoo = new ZooKeeper(Configuration.zookeeper, 3000, this);
        init();
    }

    private void init() throws IOException {
        setLeader(true); // initially everybody is a leader

        // register the leader selection watcher
        try {
            if (zoo.exists(path, false) == null) {
                zoo.create(path, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            }
            zoo.getChildren(path, true); // start watching
            zoo.create(path + "/" + this.getID(), null, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
        } catch (Exception e) {
            //e.printStackTrace();
            System.out.println("Running without zookeeper. So no leader election!");
        }
    }

    /**
     * Get the proposer ID
     * 
     * @return the ID
     */
    public int getID() {
        return ID;
    }

    /**
     * @return the send counter
     */
    public AtomicLong getSendCount() {
        return send_count;
    }

    /**
     * @return the receive counter
     */
    public AtomicLong getRecvCount() {
        return recv_count;
    }

    /**
     * @return the receive counter
     */
    public AtomicLong getRecvBytes() {
        return recv_bytes;
    }

    /**
     * @return if performance test is enabled
     */
    public boolean isPerfTest() {
        return perf_test;
    }

    /**
     * @param b
     */
    public void setPerfTest(boolean b) {
        perf_test = b;
    }

    /**
     * Is this proposer a leader
     * 
     * @return is leader
     */
    public boolean isLeader() {
        return leader;
    }

    /**
     * Set the leader state
     * 
     * @param l true if this is a leader
     * @throws IOException 
     */
    public synchronized void setLeader(boolean l) throws IOException {
        boolean old = leader;
        leader = l;
        if (old == false && l == true) { // proposer -> leader
            leader_listener.execute(new LeaderListener(this));
            for (int n = 0; n < threadCount; n++) {
                executer.execute(new ProposerListener(this));
            }
            reserver.execute(new ProposerReserver(this));
        } else if (old == true && l == false) { // leader -> proposer
            for (int n = 0; n < threadCount; n++) {
                leader_sender.execute(new LeaderSender(this));
            }
        }
    }

    /**
     * Get the paxos instance counter
     * 
     * @return the instance
     */
    public AtomicLong getInstance() {
        return globalInstance;
    }

    /**
     * This is the blocking queue for the values to propose
     * 
     * @return the values queue
     */
    public BlockingQueue<Value> getValueQueue() {
        return values;
    }

    /**
     * Get the blocking queue with the reserved promises
     * 
     * @return the promise queue
     */
    public BlockingQueue<Promise> getPromiseQueue() {
        return promises;
    }

    @Override
    public void process(WatchedEvent event) {
        int max = -1;
        try {
            if (event.getType() == EventType.NodeChildrenChanged) {
                List<String> l = zoo.getChildren(path, true);
                for (String s : l) {
                    int i = Integer.parseInt(s);
                    if (i > max) {
                        max = i;
                    }
                }
                if (max == this.getID()) {
                    System.out.println("I'm the new leader :-)!");
                    setLeader(true);
                } else {
                    System.out.println("I'm a dumb follower :-(!");
                    setLeader(false);
                }
            }
        } catch (KeeperException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * @param args
     * @throws IOException 
     * @throws NumberFormatException 
     */
    public static void main(String[] args) throws IOException {
        if (args.length > 1) {
            Proposer p = new Proposer(Integer.parseInt(args[0]), args[1]);
            if (Configuration.getConfiguration().isEmpty()) {
                Configuration.read(args[1]);
            }
            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
            String s;
            while ((s = in.readLine()) != null && s.length() != 0) {
                try {
                    if (s.contains("start")) {
                        if (!p.isPerfTest()) {
                            p.setPerfTest(true);
                            Thread t = new Thread(new StatsOutputWriter(p));
                            t.start();
                            int conc_values = 80;
                            for (int i = 0; i < conc_values; i++) {
                                p.getValueQueue().put(
                                        new Value(System.currentTimeMillis() + "" + p.getID(), new byte[6000]));
                            }
                        }
                    } else {
                        p.getValueQueue().put(new Value(System.currentTimeMillis() + "" + p.getID(), s.getBytes()));
                    }
                } catch (NumberFormatException e) {
                    System.err.println("Error while parsing input as integer!");
                } catch (InterruptedException e) {
                }
            }
            System.exit(0);
        } else {
            System.err.println("Use propose.sh <id> <config>!");
            System.exit(1);
        }
    }
}