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.IOException;
import java.net.NetworkInterface;
import java.net.StandardProtocolFamily;
import java.net.StandardSocketOptions;
import java.nio.channels.DatagramChannel;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicLong;
import ch.usi.da.paxos.api.PaxosRole;
import ch.usi.da.paxos.storage.Decision;
/**
* Name: Learner<br>
* Description: <br>
*
* Creation date: Apr 9, 2012<br>
* $Id$
*
* @author Samuel Benz benz@geoid.ch
*/
public class Learner {
private final int threadCount = 5;
private final int ID;
private final DatagramChannel channel;
private final Map<Long,Majority> instanceList = new ConcurrentHashMap<Long,Majority>(1000);
private final AtomicLong instance = new AtomicLong(1);
private final BlockingQueue<Decision> decisions = new LinkedBlockingQueue<Decision>();
private final BlockingQueue<Long> requests = new LinkedBlockingQueue<Long>();
private ExecutorService executer = Executors.newFixedThreadPool(threadCount);
private ExecutorService writer = Executors.newFixedThreadPool(1);
/**
* Public constructor
*
* @param id proposer id
* @param config path to config file
* @throws IOException
*/
public Learner(int id,String config) throws IOException{
this.ID = id;
if(Configuration.getConfiguration().isEmpty()){
Configuration.read(config);
}
NetworkInterface i = NetworkInterface.getByName(Configuration.getInterface());
this.channel = DatagramChannel.open(StandardProtocolFamily.INET)
.setOption(StandardSocketOptions.SO_REUSEADDR, true)
.bind(Configuration.getGroup(PaxosRole.Learner))
.setOption(StandardSocketOptions.IP_MULTICAST_IF, i);
this.channel.configureBlocking(false);
this.channel.join(Configuration.getGroup(PaxosRole.Learner).getAddress(), i);
for(int n=0;n<threadCount;n++){
executer.execute(new LearnerListener(this));
}
writer.execute(new LearnerWriter(this));
}
/**
* Get the proposer ID
*
* @return the ID
*/
public int getID() {
return ID;
}
/**
* Get the datagram channel
*
* @return the channel
*/
public DatagramChannel getChannel(){
return channel;
}
/**
* Return the instance list
*
* @return the instance list
*/
public AtomicLong getInstance(){
return instance;
}
/**
* Return the decision list
*
* @return the decision list
*/
public BlockingQueue<Decision> getDecisions(){
return decisions;
}
/**
* Stores a list of missing instances
*
* @return the requests list
*/
public BlockingQueue<Long> getRequests(){
return requests;
}
/**
* Return the local running majority instance List
*
* @return the local instance list
*/
public Map<Long,Majority> getInstanceList(){
return instanceList;
}
/**
* @param args
* @throws IOException
* @throws NumberFormatException
*/
public static void main(String[] args) throws IOException {
if(args.length > 1){
new Learner(Integer.parseInt(args[0]),args[1]);
}else{
System.err.println("Use learn.sh <id> <config>!");
System.exit(1);
}
}
}