Skip to content
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
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
94 changes: 94 additions & 0 deletions src/main/java/dev/oxoo2a/sim4da/BaseActor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package dev.oxoo2a.sim4da;

import java.util.Random;

public abstract class BaseActor extends Node{

public boolean isActive() {
return isActive;
}

public void setActive(boolean active) {
isActive = active;
}

private boolean isActive = false;

public float getProbability() {
return probability;
}

public void setProbability(float probability) {
this.probability = probability;
if (probability > 1f)
this.probability = 1f;
else if (probability < 0f)
this.probability = 0f;
}

private float probability = 1.0f;
final float convergence = 0.00005f;

public BaseActor(int my_id) {
super(my_id, false);
}
public BaseActor(int my_id, boolean trackClock) {
super(my_id, trackClock);
}
public BaseActor(int my_id, Clock clock ) { super(my_id, clock);}

@Override
protected void main() {

Message basic_cast = new Message().add("Sender",myId).add("isControl", "false");
Message control_cast = new Message().add("Sender",myId).add("isControl", "true");

// random decides if actor should be active on simulation start
Random r = new Random();
float random = r.nextFloat();

// (myId == 0) is reserved for the control actor so (myId == 1) will definitly send a message to the network
if (myId == 1 || random >= 0.7f)
shouldSend(basic_cast);

while (stillSimulating()) {
// receiving
Network.Message m_raw = receive();
if (m_raw == null) break; // Null == Node2Simulator time ends while waiting for a message

Message m_json = Message.fromJson(m_raw.payload);
boolean isControl = Boolean.parseBoolean(m_json.query("isControl"));

// send basic
if (!isControl)
handleBasicMessage(basic_cast);
// send control
else{
int controlID = Integer.parseInt(m_json.query("Sender"));
handleControlMessage(control_cast, controlID);
}
}

}

protected void shouldSend(Message u_cast){
Random r = new Random();
float random = r.nextFloat();
while (random <= probability ){
sendMessageToRandom(u_cast);
probability -= convergence;
random = r.nextFloat();
}
isActive = false;
}

protected int sendMessageToRandom(Message u_cast){
Random r = new Random();
int random = r.nextInt(numberOfNodes()-1) +1 ;
sendUnicast(random, u_cast);
return random;
}

protected abstract void handleControlMessage(Message control_cast, int controlID);
protected abstract void handleBasicMessage(Message basic_cast);
}
9 changes: 9 additions & 0 deletions src/main/java/dev/oxoo2a/sim4da/Clock.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package dev.oxoo2a.sim4da;

public interface Clock {

public void increase();
public void synchronize(Network.Message m);
public String getTime();

}
59 changes: 59 additions & 0 deletions src/main/java/dev/oxoo2a/sim4da/CountActor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package dev.oxoo2a.sim4da;

public class CountActor extends BaseActor{

public int getReceived() {
return received;
}

public void setReceived(int received) {
this.received = received;
}

private int received = 0;

public int getSent() {
return sent;
}

public void setSent(int sent) {
this.sent = sent;
}

private int sent = 0;
public CountActor(int my_id) {
super(my_id);
}

public CountActor(int my_id, boolean trackClock) {
super(my_id, trackClock);
}

public CountActor(int my_id, Clock clock) {
super(my_id, clock);
}

@Override
protected void handleControlMessage(Message control_cast, int controlID){
if (controlID == myId)
return;
control_cast.add("sent", sent);
control_cast.add("received", received);
control_cast.add("isActive", isActive() ? "true" : "false");
sendUnicast(controlID, control_cast);
}

@Override
protected void handleBasicMessage(Message basic_cast){
setActive(true);
received++;
shouldSend(basic_cast);
}

@Override
protected int sendMessageToRandom(Message u_cast) {
int r = super.sendMessageToRandom(u_cast);
sent++;
return r;
}
}
123 changes: 123 additions & 0 deletions src/main/java/dev/oxoo2a/sim4da/DoubleCountActor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package dev.oxoo2a.sim4da;

public class DoubleCountActor extends CountActor {

final int TERMINATION_CHECK_SEC = 3; // check termination every n seconds
private long startTime;


private int totalSent = 0;
private int totalReceived = 0;
private int controlCount = 0;

private boolean isFetchingControl = false;
private boolean allPassive = false;
private boolean isFirstCheckTerminated = false;
private boolean terminated = false;
public DoubleCountActor(int my_id) {
super(my_id, false);
}
public DoubleCountActor( int my_id, Clock clock ) { super(my_id, clock);}

@Override
protected void main() {
startTime = System.currentTimeMillis();

Message control_cast = new Message().add("Sender",myId).add("isControl", "true");

Thread threadCheck = new Thread(() -> {
while(true) {
if (terminated)
break;

long elapsedTime = System.currentTimeMillis() - startTime;
if (!isFetchingControl) {
if (elapsedTime >= TERMINATION_CHECK_SEC * 1000) {
System.out.println("Double Count Actor: Check termination");
startTime = System.currentTimeMillis();
isFetchingControl = true;
allPassive = true;
multiCast(control_cast);
}
}
}
});

Thread threadCount = new Thread(() -> {
while(true) {
// receiving
Network.Message m_raw = receive();
if (m_raw == null) break; // Null == Node2Simulator time ends while waiting for a message

Message m_json = Message.fromJson(m_raw.payload);
boolean isControl = Boolean.parseBoolean(m_json.query("isControl"));
int sender = Integer.parseInt(m_json.query("Sender"));

if (!isControl) {
setReceived(getReceived() + 1);
continue;
}
boolean isActive = Boolean.parseBoolean(m_json.query("isActive"));
int sent = Integer.parseInt(m_json.query("sent"));
int received = Integer.parseInt(m_json.query("received"));

totalSent += sent;
totalReceived += received;
controlCount++;

if (isActive)
allPassive = false;

if (controlCount == numberOfNodes()-1){
totalSent += getSent();
totalReceived += getReceived();
if (isActive())
allPassive = false;


if (!allPassive)
System.out.println("Double Count Actor: Not all actors are passive.");
else
System.out.printf("Double Count Actor: sent #%d, received #%d \n", totalSent, totalReceived);

if (totalReceived == totalSent && allPassive) {
if (isFirstCheckTerminated){
terminated = true;
System.out.println("Double Count Actor: Terminated.");
break;
}else {
isFirstCheckTerminated = true;
startTime = System.currentTimeMillis();
System.out.println("Double Count Actor: Starting second check.");
}
}else {
isFirstCheckTerminated = false;
startTime = System.currentTimeMillis();
System.out.println("Double Count Actor: Termination check failed. Check again.");
}
isFetchingControl = false;
controlCount = 0;
totalSent = 0;
totalReceived = 0;
allPassive = true;
}

}
});

threadCheck.start();
threadCount.start();

super.main();
threadCheck.interrupt();
threadCount.interrupt();
}

private void multiCast(Message control_cast){
for (int i = 0; i < numberOfNodes(); i++) {
if (i == myId)
continue;
sendUnicast(i,control_cast);
}
}
}
27 changes: 27 additions & 0 deletions src/main/java/dev/oxoo2a/sim4da/LamportClock.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package dev.oxoo2a.sim4da;

import java.util.Vector;

public class LamportClock implements Clock{

int lc = 0;

public LamportClock(){}

@Override
public void increase() {
lc++;
}

@Override
public void synchronize(Network.Message m) {
Message m_json = Message.fromJson(m.payload);
int receivedTime = Integer.parseInt(m_json.query("Time"));
lc = Math.max(lc+1, receivedTime);
}

@Override
public String getTime() {
return String.valueOf(lc);
}
}
46 changes: 46 additions & 0 deletions src/main/java/dev/oxoo2a/sim4da/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package dev.oxoo2a.sim4da;

public class Main {

public static void main(String[] args) {
int n_nodes = 5;
int duration = 26;
Simulator s = Simulator.createDefaultSimulator(n_nodes);

int type = 0; // 0 = Counter Actor, 1 = Vector Actor

for (int id=0; id<n_nodes; id++) {
/*
// u1, sending messages and tracking time withLamport or Vertex Clock
TokenRingNode n = new TokenRingNode(id, new LamportClock());
*/

if (type == 0) {
if (id == 0) {
// u2 Double Count Actors that detects termination
DoubleCountActor first = new DoubleCountActor(id);
s.attachNode(id, first);
} else {
// u2 sending messages with Actors and detect termination
BaseActor n = new CountActor(id);
s.attachNode(id, n);
}
}else{
if (id == 0) {
// u2 Vector Controll Actor that detects termination
VectorControlActor first = new VectorControlActor(id, n_nodes);
s.attachNode(id, first);
} else {
// u2 sending messages with Actors and detect termination
VectorActor n = new VectorActor(id, n_nodes);
s.attachNode(id, n);
}
}
}
try {
s.runSimulation(duration);
} catch (InstantiationException e) {
throw new RuntimeException(e);
}
}
}
2 changes: 2 additions & 0 deletions src/main/java/dev/oxoo2a/sim4da/Network.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ public Message(int sender_id, int receiver_id, MessageType type, String payload
this.receiver_id = receiver_id;
this.type = type;
this.payload = payload;
isControl = false;
}
public int sender_id;
public int receiver_id;
public MessageType type;
public String payload;
public boolean isControl;

public String toString () {
String r = "Network::Message(sender="+sender_id+",receiver="+receiver_id+",";
Expand Down
Loading