Skip to content

Yolo #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions src/ChordNameService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import java.net.InetSocketAddress;

/**
*
* Interface for the Chord naming service. Each peer is named by an IP
* address and a port, technically an InetSocketAddress. Each
* InetSocketAddress is mapped into a key, an unsigned 31-bit integer,
* by taking hash=InetSocketAddress.hashCode() and letting key =
* abs(hash*1073741651 % 2147483647), where abs() is absolute value.
* This key is used to arrange all InetSocketAddress's into a ring
* with the current peers being responsible for each their interval of
* the key space, according to the Chord network topology. The
* interface allows to enter and leave a chord group and allows to
* find the name of a peer currently responsible for a given key.
*/


public interface ChordNameService extends Runnable {

/**
* Compute the key of a given name. Returns a positive 31-bit
* integer, hased as to be "random looking" even for similar
* names.
*/
public int keyOfName(InetSocketAddress name);

/**
* Used by the first group member. Specifies the port on
* which this founding peer is listening for new peers to join
* or leave. The name of the foudning peer is its local IP
* address and the given port. Its key is derived from the
* name using the method described above.
*/
public void createGroup();

/**
* Used to join a Chord group. This takes place by contacting
* one of the existing peers of the Chord group. The new peer
* has the name specified by the local IP address and the
* given port. The key of the new peer is derived from its
* name using the method described above.
*
* @param knownPeer The IP address and port of the known peer.
*/
public void joinGroup(InetSocketAddress knownPeer);

/**
* Returns the name of this peer. May only be called after a
* group has been formed or joined.
*/
public InetSocketAddress getChordName();

/**
* Makes this instance of ChordNameService leave the peer
* group. The other peers should be informed of this and the
* Chord network updated appropriately.
*/
public void leaveGroup();

/**
* Starts the thread which manages this peers participation in
* the Chord network.
*/
public void run();

}
160 changes: 160 additions & 0 deletions src/ChordNameServiceImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.*;

public class ChordNameServiceImpl {

private DistributedTextEditor dte;
private int port;
protected InetSocketAddress myName;
protected int myKey;
private InetSocketAddress suc;
private InetSocketAddress pre;
private InetSocketAddress connectedAt;
private ServerSocket serverSocket;

private Socket preSocket, sucSocket;
private DisconnectThread disconnectThread;
private Socket hack;

public Socket getSucSocket() {
return sucSocket;
}

public void setSucSocket(Socket sucSocket) {
this.sucSocket = sucSocket;
}

public Socket getPreSocket() {
return preSocket;
}

public void setPreSocket(Socket preSocket) {
this.preSocket = preSocket;
}

private boolean active;
private boolean first;
private ServerThread serverThread;

public ChordNameServiceImpl(InetSocketAddress myName, DistributedTextEditor dte){
this.myName = myName;
this.port = myName.getPort();
this.dte = dte;
}

public int keyOfName(InetSocketAddress name) {
int tmp = name.hashCode()*1073741651 % 2147483647;
if (tmp < 0) { tmp = -tmp; }
return tmp;
}

public InetSocketAddress getChordName() {
return myName;
}

public void createGroup(){
serverThread = new ServerThread(dte,this);
new Thread(serverThread).start();
}

public void joinGroup(InetSocketAddress knownPeer) {
active = true;
connectedAt = knownPeer;
try {
// Setup successor
sucSocket = new Socket(knownPeer.getAddress(),port);


dte.newEventPlayer(sucSocket, myKey);

// Wait for new predecessor
ServerSocket server = new ServerSocket(port);
System.out.println("waiting");
final ServerSocket finalServer = server;
new Thread(new Runnable(){
@Override
public void run() {
try {
Thread.sleep(1000);
System.out.println("about to close");
finalServer.close();
System.out.println("closed");
} catch (InterruptedException | IOException e) {
e.printStackTrace();
}
}
}).start();
preSocket = server.accept();
System.out.println("Done waiting");

System.out.println("else");
// Start listening for disconnects from successor
disconnectThread = new DisconnectThread(dte, this, sucSocket);
new Thread(disconnectThread).start();

dte.newEventReplayer(preSocket, myKey);

// Keep listening for new joins
serverThread = new ServerThread(dte, this, server);
new Thread(serverThread).start();

}
catch (SocketException e1){
first = true;
System.out.println("first");
preSocket = sucSocket;
dte.newEventReplayer(preSocket, myKey);
try {
hack = new Socket(preSocket.getInetAddress(), port+1);
// Start listening for disconnects from successor
disconnectThread = new DisconnectThread(dte,this,hack);
new Thread(disconnectThread).start();

// Keep listening for new joins
ServerSocket server = new ServerSocket(port);
serverThread = new ServerThread(dte,this,server);
new Thread(serverThread).start();
} catch (IOException e) {
e.printStackTrace();
}

}
catch (IOException e) {
e.printStackTrace();
}
}
public void notFirst(){
first = false;
}

public void leaveGroup() {

try {
ObjectOutputStream disconnectStream = null;
if (first) {
disconnectStream = new ObjectOutputStream(hack.getOutputStream());
} else
disconnectStream = new ObjectOutputStream(preSocket.getOutputStream());

disconnectStream.writeObject(new DisconnectEvent(sucSocket.getInetAddress()));
preSocket.close();
sucSocket.close();

} catch (IOException e) {
e.printStackTrace();
}

}

/*
* If joining we should now enter the existing group and
* should at some point register this peer on its port if not
* already done and start listening for incoming connection
* from other peers who want to enter or leave the
* group. After leaveGroup() was called, the run() method
* should return so that the thread running it might
* terminate.
*/
}
7 changes: 7 additions & 0 deletions src/ConnectEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import java.io.Serializable;

public class ConnectEvent implements Serializable {

private boolean krestenInsists = true;

}
25 changes: 11 additions & 14 deletions src/DisconnectEvent.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
import java.io.Serializable;
import java.net.InetAddress;

/**
* DisconnectEvent is a MyTextEvent used to let all the threads know
* when to close. It contains a boolean to let the threads close
* in the right order, and in the end close the socket.
* Created by Kresten Axelsen on 27-04-2015.
* Originally created by Kresten Axelsen on 27-04-3015, a day we will all remember.
*/
public class DisconnectEvent extends MyTextEvent {
DisconnectEvent(int offset) {
super(offset);
}
private boolean shouldDisconnect;
public class DisconnectEvent implements Serializable {
InetAddress newSuccessor;

public boolean shouldDisconnect() {
return shouldDisconnect;
public DisconnectEvent(InetAddress successor) {
newSuccessor = successor;
}

public void setShouldDisconnect() {
shouldDisconnect = true;
public InetAddress getNewSuccessor() {
return newSuccessor;
}
}
}
49 changes: 49 additions & 0 deletions src/DisconnectThread.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.InetAddress;
import java.net.Socket;

public class DisconnectThread implements Runnable {

private Socket socket;
private final ChordNameServiceImpl cns;
private final DistributedTextEditor dte;

public DisconnectThread(DistributedTextEditor dte, ChordNameServiceImpl cns, Socket predecessor) {
socket = predecessor;
this.cns = cns;
this.dte = dte;
}

@Override
public void run() {
try {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
while(true) {
ObjectInputStream disconnectStream = new ObjectInputStream(socket.getInputStream());
Object de;
while ((de = disconnectStream.readObject()) != null) {
if (de instanceof DisconnectEvent) {
InetAddress newSuccessor = ((DisconnectEvent) de).getNewSuccessor();
cns.setSucSocket(new Socket(newSuccessor, cns.getChordName().getPort()));

dte.newEventPlayer(cns.getSucSocket(), cns.keyOfName(cns.getChordName()));

// New successor
socket = cns.getSucSocket();
} else if (de instanceof ConnectEvent) {
cns.setSucSocket(cns.getPreSocket());
}
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Loading