├── Distributed Consensus ├── Exercise-Consensus.json ├── Exercise-Consensus.log ├── Exercise-Consensus.md └── Exercise-Consensus.scala ├── Eventually Perfect Failure Detector ├── EventuallyPerfectFailureDetector.json ├── EventuallyPerfectFailureDetector.md └── EventuallyPerfectFailureDetector.scala ├── Exercise Broadcast Abstractions ├── Exercise-_Broadcast_Abstractions.json ├── Exercise-_Broadcast_Abstractions.md └── Exercise-_Broadcast_Abstractions.scala ├── Exercise SharedMemory ├── Exercise-SharedMemory.json ├── Exercise-SharedMemory.log ├── Exercise-SharedMemory.md └── Exercise-SharedMemory.scala ├── Game of Life ├── Game of Life.json ├── Game of Life.scala └── Game of life.md └── README.md /Distributed Consensus/Exercise-Consensus.json: -------------------------------------------------------------------------------- 1 | {"paragraphs":[{"text":"%md\n\n## Distributed Consensus\n\nIn this final programming assignment for Part I of the course you will have to complete the implementation of a variation of the famous Paxos algorithm.\n\nWhen you are done you simply have to export your notebook and then upload it in the \"Programming Exercise 5\" page.\n\n**Things to Remember**:\n1. Basic components such as `PerfectLink` and `Best-Effort Broadcast` are already provided. No need to implement them.\n2. Execute the imports defined below **before** compiling your component implementations.\n3. We recommend making use of the component state and internal messages we have provided, if any, to complete the implementation logic.\n4. You can always print messages to the output log, from within handlers to see what happens during the simulation. e.g. `println(s\"Process $self delivers message $msg\");`\n5. Remember that during the simulation check you can print and observe the simulation time, i.e. with `System.currentTimeMillis()`.\n5. Do not forget to run the checker code block after each component implementation to ensure that all properties are satisfied **before** exporting and submitting the notebook.\n6. You can always restart the Kompics Interpreter to start fresh (Interpreter→KompicsInterpreter→Click Restart)\n\nGood luck! :)","user":"anonymous","dateUpdated":"2018-01-09T16:35:23+0000","config":{"editorMode":"ace/mode/markdown","colWidth":12,"editorHide":true,"results":[{"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}}],"enabled":true,"fontSize":9,"editorSetting":{"language":"markdown","editOnDblClick":true},"tableHide":false},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"
\n

Distributed Consensus

\n

In this final programming assignment for Part I of the course you will have to complete the implementation of a variation of the famous Paxos algorithm.

\n

When you are done you simply have to export your notebook and then upload it in the “Programming Exercise 5” page.

\n

Things to Remember:
1. Basic components such as PerfectLink and Best-Effort Broadcast are already provided. No need to implement them.
2. Execute the imports defined below before compiling your component implementations.
3. We recommend making use of the component state and internal messages we have provided, if any, to complete the implementation logic.
4. You can always print messages to the output log, from within handlers to see what happens during the simulation. e.g. println(s"Process $self delivers message $msg");
5. Remember that during the simulation check you can print and observe the simulation time, i.e. with System.currentTimeMillis().
5. Do not forget to run the checker code block after each component implementation to ensure that all properties are satisfied before exporting and submitting the notebook.
6. You can always restart the Kompics Interpreter to start fresh (Interpreter→KompicsInterpreter→Click Restart)

\n

Good luck! :)

\n
"}]},"apps":[],"jobName":"paragraph_1515514951750_-1959993476","id":"20160927-134633_1462429338","dateCreated":"2018-01-09T16:22:31+0000","dateStarted":"2018-01-09T16:35:23+0000","dateFinished":"2018-01-09T16:35:23+0000","status":"FINISHED","progressUpdateIntervalMs":500,"focus":true,"$$hashKey":"object:348"},{"text":"import se.kth.edx.id2203.core.ExercisePrimitives.AddressUtils._\nimport se.kth.edx.id2203.core.Ports._\nimport se.kth.edx.id2203.validation._\nimport se.sics.kompics.network._\nimport se.sics.kompics.sl.{Init, _}\nimport se.sics.kompics.{KompicsEvent, ComponentDefinition => _, Port => _}\nimport scala.language.implicitConversions\nimport scala.collection.mutable.ListBuffer;\n\nimport se.sics.kompics.timer.{ScheduleTimeout, Timeout, Timer}\n","user":"anonymous","dateUpdated":"2018-01-11T09:25:51+0000","config":{"editorMode":"ace/mode/scala","colWidth":12,"tableHide":false,"enabled":true,"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}},"fontSize":9,"results":{},"editorSetting":{"language":"scala","editOnDblClick":false}},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"import se.kth.edx.id2203.core.ExercisePrimitives.AddressUtils._
import se.kth.edx.id2203.core.Ports._
import se.kth.edx.id2203.validation._
import se.sics.kompics.network._
import se.sics.kompics.sl.{Init, _}
import se.sics.kompics.{KompicsEvent, ComponentDefinition=>_, Port=>_}
import scala.language.implicitConversions
import scala.collection.mutable.ListBuffer
import se.sics.kompics.timer.{ScheduleTimeout, Timeout, Timer}
"}]},"apps":[],"jobName":"paragraph_1515514951751_-1959993476","id":"20160830-154917_187608468","dateCreated":"2018-01-09T16:22:31+0000","dateStarted":"2018-01-11T09:25:51+0000","dateFinished":"2018-01-11T09:25:51+0000","status":"FINISHED","progressUpdateIntervalMs":500,"$$hashKey":"object:349"},{"text":"%md\n\n## Leader-less Obstraction-Free Paxos for Single Value Consensus ##\n\nA (single value) Consensus Abstraction, in Kompics terms, is a component that **provides** the following port *(already imported in the notebook)*.\n\n class Consensus extends Port{\n request[C_Propose];\n indication[C_Decide];\n }\n\nAn **Consensus** component should request value proposals (`C_Propose`) and respond with decided value events (`C_Decide`) respectively as defined below:\n\n case class C_Decide(value: Any) extends KompicsEvent;\n case class C_Propose(value: Any) extends KompicsEvent;\n\nThe following properties define the expected behavior of a consensus abstraction more specifically:\n\n1. **Validity**: *Only proposed values may be decided.*\n2. **Uniform Agreement**: *No two nodes decide different values.*\n3. **Integrity**: *Each node can decide a value at most once.*\n4. **Termination**: *Every node eventually decides a value.*\n \nThe recommended algorithm to use is the the one we call \"Leaderless Repeatable Paxos\" which initiates new proposal rounds until a decision has been made.\nYou can find the algorithm in the following [document](https://courses.edx.org/asset-v1:KTHx+ID2203.1x+2016T3+type@asset+block@paxos-consensus.pdf) (pages 2-3).\n","user":"anonymous","dateUpdated":"2018-01-11T19:08:55+0000","config":{"editorMode":"ace/mode/markdown","colWidth":12,"editorHide":true,"results":[{"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}}],"enabled":true,"fontSize":9,"editorSetting":{"language":"markdown","editOnDblClick":true},"tableHide":false},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"
\n

Leader-less Obstraction-Free Paxos for Single Value Consensus

\n

A (single value) Consensus Abstraction, in Kompics terms, is a component that provides the following port (already imported in the notebook).

\n
 class Consensus extends Port{\n   request[C_Propose];\n   indication[C_Decide];\n }\n
\n

An Consensus component should request value proposals (C_Propose) and respond with decided value events (C_Decide) respectively as defined below:

\n
 case class C_Decide(value: Any) extends KompicsEvent;\n case class C_Propose(value: Any) extends KompicsEvent;\n
\n

The following properties define the expected behavior of a consensus abstraction more specifically:

\n
    \n
  1. Validity: Only proposed values may be decided.
  2. \n
  3. Uniform Agreement: No two nodes decide different values.
  4. \n
  5. Integrity: Each node can decide a value at most once.
  6. \n
  7. Termination: Every node eventually decides a value.
  8. \n
\n

The recommended algorithm to use is the the one we call “Leaderless Repeatable Paxos” which initiates new proposal rounds until a decision has been made.
You can find the algorithm in the following document (pages 2-3).

\n
"}]},"apps":[],"jobName":"paragraph_1515514951752_-1961917220","id":"20160930-115754_781424547","dateCreated":"2018-01-09T16:22:31+0000","dateStarted":"2018-01-11T19:08:55+0000","dateFinished":"2018-01-11T19:08:55+0000","status":"FINISHED","progressUpdateIntervalMs":500,"$$hashKey":"object:350"},{"text":" case class Prepare(proposalBallot: (Int, Int)) extends KompicsEvent;\n case class Promise(promiseBallot: (Int, Int), acceptedBallot: (Int, Int), acceptedValue: Option[Any]) extends KompicsEvent;\n case class Accept(acceptBallot: (Int, Int), proposedValue: Any) extends KompicsEvent;\n case class Accepted(acceptedBallot: (Int, Int)) extends KompicsEvent;\n case class Nack(ballot: (Int, Int)) extends KompicsEvent;\n case class Decided(decidedValue: Any) extends KompicsEvent;\n\n /**\n * This augments tuples with comparison operators implicitly, which you can use in your code, for convenience. \n * examples: (1,2) > (1,4) yields 'false' and (5,4) <= (7,4) yields 'true' \n */\n implicit def addComparators[A](x: A)(implicit o: math.Ordering[A]): o.Ops = o.mkOrderingOps(x);\n \n //HINT: After you execute the latter implicit ordering you can compare tuples as such within your component implementation:\n (1,2) <= (1,4);","user":"anonymous","dateUpdated":"2018-01-11T09:25:54+0000","config":{"editorMode":"ace/mode/scala","colWidth":12,"tableHide":false,"enabled":true,"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}},"fontSize":9,"results":{},"editorSetting":{"language":"scala","editOnDblClick":false}},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"defined class Prepare
defined class Promise
defined class Accept
defined class Accepted
defined class Nack
defined class Decided
addComparators: [A](x: A)(implicit o: scala.math.Ordering[A])o.Ops
res9: Boolean = true
"}]},"apps":[],"jobName":"paragraph_1515514951752_-1961917220","id":"20160830-154940_1300846994","dateCreated":"2018-01-09T16:22:31+0000","dateStarted":"2018-01-11T09:25:54+0000","dateFinished":"2018-01-11T09:25:55+0000","status":"FINISHED","progressUpdateIntervalMs":500,"$$hashKey":"object:351"},{"text":"\nclass Paxos(paxosInit: Init[Paxos]) extends ComponentDefinition {\n\n //Port Subscriptions for Paxos\n\n val consensus = provides[Consensus];\n val beb = requires[BestEffortBroadcast];\n val plink = requires[PerfectLink];\n \n //Internal State of Paxos\n val (rank, numProcesses) = paxosInit match {\n case Init(s: Address, qSize: Int) => (toRank(s), qSize)\n }\n\n //Proposer State\n var round = 0;\n var proposedValue: Option[Any] = None;\n var promises: ListBuffer[((Int, Int), Option[Any])] = ListBuffer.empty;\n var numOfAccepts = 0;\n var decided = false;\n\n //Acceptor State\n var promisedBallot = (0, 0);\n var acceptedBallot = (0, 0);\n var acceptedValue: Option[Any] = None;\n\n def propose() = {\n if(!decided){\n round = round + 1;\n numOfAccepts = 0;\n promises = ListBuffer.empty;\n println(s\"($rank -> $numProcesses) triggering BEB_Broadcast(Prepare(round $round, rank $rank))\");\n trigger(BEB_Broadcast(Prepare(round,rank)) -> beb);\n }\n }\n\n consensus uponEvent {\n case C_Propose(value) => handle {\n proposedValue = Some(value);\n propose();\n }\n }\n\n\n beb uponEvent {\n \n case BEB_Deliver(src, prep: Prepare) => handle {\n if(promisedBallot < prep.proposalBallot){\n promisedBallot = prep.proposalBallot;\n println(s\"($rank -> $numProcesses) triggering PL_Send($src, Promise(promisedBallot $promisedBallot, acceptedBallot $acceptedBallot, acceptedValue $acceptedValue))\");\n trigger(PL_Send(src, Promise(promisedBallot, acceptedBallot, acceptedValue))-> plink);\n } else {\n println(s\"($rank -> $numProcesses) triggering PL_Send($src, Nack(prep.proposalBallot $prep.proposalBallot))\");\n trigger(PL_Send(src, Nack(prep.proposalBallot))-> plink);\n }\n };\n\n case BEB_Deliver(src, acc: Accept) => handle {\n if(promisedBallot <= acc.acceptBallot){\n acceptedBallot = acc.acceptBallot;\n promisedBallot = acceptedBallot;\n acceptedValue = Some(acc.proposedValue);\n println(s\"($rank -> $numProcesses) triggering PL_Send($src, Accepted(acceptBallot $acc.acceptBallot))\");\n trigger(PL_Send(src, Accepted(acc.acceptBallot))-> plink);\n } else {\n println(s\"($rank -> $numProcesses) triggering PL_Send($src, Nack(acceptBallot $acc.acceptBallot))\");\n trigger(PL_Send(src, Nack(acc.acceptBallot))-> plink);\n }\n };\n\n case BEB_Deliver(src, dec : Decided) => handle {\n if(!decided){\n println(s\"($rank -> $numProcesses) triggering Decided(dec.decidedValue $dec.decidedValue)\");\n trigger(C_Decide(dec.decidedValue) -> consensus);\n decided = true;\n }\n }\n }\n\n plink uponEvent {\n\n case PL_Deliver(src, prepAck: Promise) => handle {\n if ((round, rank) == prepAck.promiseBallot) {\n promises += ((prepAck.acceptedBallot, prepAck.acceptedValue));\n if(promises.size > (numProcesses + 1) / 2){\n var (maxBallot, value) = promises.maxBy { case (key, value) => key };\n if (value.isDefined) {\n proposedValue = value\n }\n println(s\"($rank -> $numProcesses) triggering BEB_Broadcast(Accept((round $round, rank $rank), proposedValue $proposedValue))\");\n trigger(BEB_Broadcast(Accept((round, rank), proposedValue.get)) -> beb);\n }\n }\n };\n\n case PL_Deliver(src, accAck: Accepted) => handle {\n if ((round, rank) == accAck.acceptedBallot) {\n numOfAccepts = numOfAccepts + 1;\n if(numOfAccepts == (numProcesses + 1) / 2){\n println(s\"($rank -> $numProcesses) triggering BEB_Broadcast(Decided(proposedValue $proposedValue))\");\n trigger(BEB_Broadcast(Decided(proposedValue)) -> beb);\n }\n }\n };\n\n case PL_Deliver(src, nack: Nack) => handle {\n if ((round, rank) == nack.ballot) {\n propose()\n }\n }\n }\n \n \n};","user":"anonymous","dateUpdated":"2018-01-11T19:23:58+0000","config":{"editorMode":"ace/mode/scala","colWidth":12,"tableHide":false,"enabled":true,"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}},"fontSize":9,"results":{},"editorSetting":{"language":"scala","editOnDblClick":false}},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"defined class Paxos
"}]},"apps":[],"jobName":"paragraph_1515514951752_-1961917220","id":"20160830-154952_592749615","dateCreated":"2018-01-09T16:22:31+0000","dateStarted":"2018-01-11T19:23:58+0000","dateFinished":"2018-01-11T19:23:59+0000","status":"FINISHED","progressUpdateIntervalMs":500,"$$hashKey":"object:352"},{"text":"checkSingleValueConsensus[Paxos]();","dateUpdated":"2018-01-11T19:24:02+0000","config":{"editorMode":"ace/mode/scala","colWidth":12,"tableHide":false,"enabled":true,"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}},"fontSize":9,"results":{},"editorSetting":{"language":"scala","editOnDblClick":false}},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1515514951752_-1961917220","id":"20160830-155009_392534435","dateCreated":"2018-01-09T16:22:31+0000","status":"FINISHED","progressUpdateIntervalMs":500,"$$hashKey":"object:353","user":"anonymous","dateFinished":"2018-01-11T19:24:05+0000","dateStarted":"2018-01-11T19:24:02+0000","results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"
Your submission has been locally simulated and validated.

Click Here to view the output of the simulation.





Correction Results
PASSED Validity ✔: Every value decided has been previously proposed
PASSED Uniform Agreement ✔: There were no two nodes deciding different values
PASSED Integrity ✔: Each node decided a value at most once
PASSED Termination ✔: Each node eventually decides

Final Comments
**************
Congratulations! Your implementation of the 'Single Value Consensus' satisfies all properties!
A unique token has been generated for your submission right below. Please do not edit.

{\"gradingToken\":[45,45,45,45,45,66,69,71,73,78,32,80,71,80,32,77,69,83,83,65,71,69,45,45,45,45,45,10,86,101,114,115,105,111,110,58,32,66,67,80,71,32,118,49,46,53,53,10,10,104,81,73,77,65,57,79,116,77,118,84,69,98,74,49,102,65,81,47,47,86,122,106,113,57,49,84,120,52,47,114,101,122,90,66,47,77,97,88,103,84,117,80,84,89,104,113,54,55,100,50,90,67,81,102,83,79,48,110,113,106,55,112,84,10,99,71,51,74,107,51,108,85,117,74,120,85,69,50,51,69,57,122,48,78,47,88,71,81,107,110,120,78,72,120,86,67,87,115,69,103,71,98,74,89,68,98,110,118,121,57,104,80,113,78,120,108,122,79,81,68,72,77,84,52,102,107,116,101,10,115,49,119,50,89,108,113,113,122,79,122,110,50,78,52,121,120,53,67,85,77,50,110,50,117,114,106,43,56,81,109,99,119,70,102,47,70,90,82,49,47,75,120,116,100,87,105,116,102,48,99,98,90,108,86,111,78,98,47,86,102,78,80,72,10,104,75,121,114,75,79,114,104,89,100,53,56,43,109,82,87,50,76,82,121,109,73,47,80,113,121,109,89,100,122,82,118,105,74,113,110,116,84,119,79,88,70,105,117,69,75,84,69,67,83,100,114,49,70,72,65,78,107,89,86,82,76,107,121,10,84,121,50,43,86,116,49,50,77,74,108,102,113,118,50,83,86,80,73,48,122,82,105,104,89,50,79,113,67,112,104,115,75,112,68,77,56,85,122,66,107,54,71,75,55,106,73,101,48,86,71,115,110,97,88,54,80,68,53,85,69,100,69,89,10,103,47,79,108,70,70,114,72,65,107,76,112,66,82,49,99,97,84,101,117,113,82,99,98,52,118,67,107,67,56,67,53,76,90,73,65,120,108,56,57,47,122,69,57,87,87,99,118,100,76,107,69,110,66,116,65,70,80,47,119,74,43,52,105,10,99,100,57,66,108,84,90,53,102,80,72,89,57,70,82,65,70,98,100,50,82,53,72,120,100,114,76,69,47,110,84,88,120,50,106,89,104,77,57,103,76,67,55,118,110,49,67,49,106,72,82,76,87,54,85,114,98,69,76,90,84,105,57,102,10,114,118,98,111,88,99,74,56,68,69,78,69,120,43,56,113,70,72,49,100,82,54,109,108,114,107,115,108,118,115,79,113,80,47,118,52,76,53,57,43,56,67,68,120,81,115,79,54,82,55,47,99,111,43,119,109,50,74,47,65,67,115,100,87,10,66,51,85,108,113,50,120,82,72,109,71,102,55,84,119,50,97,113,83,118,83,73,57,119,55,77,52,98,100,106,56,74,100,108,78,55,103,113,110,99,81,52,55,85,82,73,80,50,102,122,65,102,88,116,112,67,110,90,97,49,74,48,108,111,10,80,56,107,76,122,104,106,86,119,115,80,102,56,81,54,114,98,73,71,113,74,69,104,56,109,87,77,110,43,69,88,73,98,103,113,108,70,55,79,107,78,79,104,106,90,116,122,84,107,76,113,81,82,75,107,89,87,122,43,100,66,77,50,97,10,99,90,98,70,74,74,89,106,121,122,121,88,105,81,97,68,75,109,76,120,79,104,102,57,49,52,75,85,120,51,114,106,43,83,86,110,53,120,50,75,86,118,50,51,81,112,80,79,81,77,108,104,97,97,110,68,117,50,81,117,109,108,110,83,10,119,69,103,66,49,81,85,117,111,103,97,83,80,113,54,78,90,97,101,114,99,86,105,109,111,99,87,57,87,118,105,54,118,89,70,51,113,73,81,74,75,121,73,100,78,109,109,69,83,84,87,65,49,57,65,102,47,57,43,52,84,105,119,82,10,122,79,72,101,116,113,120,47,84,90,98,65,99,69,74,79,65,54,43,99,108,47,66,71,48,54,85,115,55,85,69,100,49,116,67,68,56,117,53,81,72,100,50,88,70,78,79,90,43,56,88,98,111,56,107,49,50,100,65,70,55,105,97,72,10,66,66,112,74,107,43,90,77,103,86,49,73,106,87,73,81,50,55,57,75,84,49,50,121,103,67,48,75,87,102,55,65,76,99,85,115,117,98,88,102,109,56,121,66,73,106,88,72,109,109,109,84,107,52,68,68,48,67,81,107,80,102,117,104,10,76,50,80,49,75,80,48,78,82,54,113,104,79,68,56,107,75,89,90,49,79,114,89,122,108,66,84,75,114,109,88,82,87,107,72,104,57,79,68,100,43,49,43,115,84,54,117,54,121,116,72,51,101,85,72,97,100,67,70,79,49,71,110,90,10,112,106,47,110,72,105,90,119,85,114,72,106,115,73,119,48,56,74,107,115,65,56,57,111,65,78,82,68,112,78,120,116,70,99,49,105,49,76,54,79,85,114,120,87,107,101,118,122,121,51,71,66,52,120,82,121,47,54,80,113,121,69,106,54,10,80,102,121,53,89,81,71,65,54,100,114,54,107,67,43,80,75,54,48,74,54,116,50,54,53,105,75,108,43,54,73,108,81,83,69,61,10,61,79,119,121,53,10,45,45,45,45,45,69,78,68,32,80,71,80,32,77,69,83,83,65,71,69,45,45,45,45,45,10]}
res16: Boolean = true
"}]}},{"dateUpdated":"2018-01-09T16:22:31+0000","config":{"editorMode":"ace/mode/scala","colWidth":12,"tableHide":false,"enabled":true,"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}},"fontSize":9,"results":{},"editorSetting":{"language":"scala","editOnDblClick":false}},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1515514951752_-1961917220","id":"20160830-155043_337959288","dateCreated":"2018-01-09T16:22:31+0000","status":"READY","errorMessage":"","progressUpdateIntervalMs":500,"$$hashKey":"object:354"}],"name":"Exercise-Consensus","id":"2D4MCXHAJ","angularObjects":{"2BKQCVH92:shared_process":[],"2CVXXPNWV:shared_process":[]},"config":{"looknfeel":"default","personalizedMode":"false"},"info":{}} -------------------------------------------------------------------------------- /Distributed Consensus/Exercise-Consensus.log: -------------------------------------------------------------------------------- 1 | SLF4J: Class path contains multiple SLF4J bindings. 2 | SLF4J: Found binding in [jar:file:/usr/zeppelin/interpreter/kompics/slf4j-log4j12-1.7.10.jar!/org/slf4j/impl/StaticLoggerBinder.class] 3 | SLF4J: Found binding in [jar:file:/usr/zeppelin/zeppelin-interpreter/target/lib/slf4j-log4j12-1.7.10.jar!/org/slf4j/impl/StaticLoggerBinder.class] 4 | SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. 5 | SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory] 6 | (1 -> 4) triggering BEB_Broadcast(Prepare(round 1, rank 1)) 7 | (2 -> 4) triggering BEB_Broadcast(Prepare(round 1, rank 2)) 8 | (3 -> 4) triggering BEB_Broadcast(Prepare(round 1, rank 3)) 9 | (1 -> 4) triggering PL_Send(TAddress(/192.168.2.1:1000), Promise(promisedBallot (1,1), acceptedBallot (0,0), acceptedValue None)) 10 | (4 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Promise(promisedBallot (1,3), acceptedBallot (0,0), acceptedValue None)) 11 | (1 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Promise(promisedBallot (1,2), acceptedBallot (0,0), acceptedValue None)) 12 | (3 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Promise(promisedBallot (1,3), acceptedBallot (0,0), acceptedValue None)) 13 | (2 -> 4) triggering PL_Send(TAddress(/192.168.2.1:1000), Promise(promisedBallot (1,1), acceptedBallot (0,0), acceptedValue None)) 14 | (2 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Promise(promisedBallot (1,2), acceptedBallot (0,0), acceptedValue None)) 15 | (3 -> 4) triggering PL_Send(TAddress(/192.168.2.1:1000), Nack(prep.proposalBallot Prepare((1,1)).proposalBallot)) 16 | (4 -> 4) triggering PL_Send(TAddress(/192.168.2.1:1000), Nack(prep.proposalBallot Prepare((1,1)).proposalBallot)) 17 | (3 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Nack(prep.proposalBallot Prepare((1,2)).proposalBallot)) 18 | (4 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Nack(prep.proposalBallot Prepare((1,2)).proposalBallot)) 19 | (1 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Promise(promisedBallot (1,3), acceptedBallot (0,0), acceptedValue None)) 20 | (2 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Promise(promisedBallot (1,3), acceptedBallot (0,0), acceptedValue None)) 21 | (3 -> 4) triggering BEB_Broadcast(Accept((round 1, rank 3), proposedValue Some(370700571))) 22 | (2 -> 4) triggering BEB_Broadcast(Prepare(round 2, rank 2)) 23 | (1 -> 4) triggering BEB_Broadcast(Prepare(round 2, rank 1)) 24 | (3 -> 4) triggering BEB_Broadcast(Accept((round 1, rank 3), proposedValue Some(370700571))) 25 | (3 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Promise(promisedBallot (2,2), acceptedBallot (0,0), acceptedValue None)) 26 | (1 -> 4) triggering PL_Send(TAddress(/192.168.2.1:1000), Promise(promisedBallot (2,1), acceptedBallot (0,0), acceptedValue None)) 27 | (4 -> 4) triggering PL_Send(TAddress(/192.168.2.1:1000), Promise(promisedBallot (2,1), acceptedBallot (0,0), acceptedValue None)) 28 | (2 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Promise(promisedBallot (2,2), acceptedBallot (0,0), acceptedValue None)) 29 | (1 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Promise(promisedBallot (2,2), acceptedBallot (0,0), acceptedValue None)) 30 | (4 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Promise(promisedBallot (2,2), acceptedBallot (0,0), acceptedValue None)) 31 | (2 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Nack(acceptBallot Accept((1,3),370700571).acceptBallot)) 32 | (4 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Nack(acceptBallot Accept((1,3),370700571).acceptBallot)) 33 | (3 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Nack(acceptBallot Accept((1,3),370700571).acceptBallot)) 34 | (1 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Nack(acceptBallot Accept((1,3),370700571).acceptBallot)) 35 | (3 -> 4) triggering PL_Send(TAddress(/192.168.2.1:1000), Nack(prep.proposalBallot Prepare((2,1)).proposalBallot)) 36 | (2 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Nack(acceptBallot Accept((1,3),370700571).acceptBallot)) 37 | (2 -> 4) triggering PL_Send(TAddress(/192.168.2.1:1000), Nack(prep.proposalBallot Prepare((2,1)).proposalBallot)) 38 | (1 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Nack(acceptBallot Accept((1,3),370700571).acceptBallot)) 39 | (1 -> 4) triggering BEB_Broadcast(Prepare(round 3, rank 1)) 40 | (2 -> 4) triggering BEB_Broadcast(Accept((round 2, rank 2), proposedValue Some(-962504004))) 41 | (3 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Nack(acceptBallot Accept((1,3),370700571).acceptBallot)) 42 | (3 -> 4) triggering BEB_Broadcast(Prepare(round 2, rank 3)) 43 | (4 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Nack(acceptBallot Accept((1,3),370700571).acceptBallot)) 44 | (2 -> 4) triggering BEB_Broadcast(Accept((round 2, rank 2), proposedValue Some(-962504004))) 45 | (3 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Accepted(acceptBallot Accept((2,2),-962504004).acceptBallot)) 46 | (4 -> 4) triggering PL_Send(TAddress(/192.168.2.1:1000), Promise(promisedBallot (3,1), acceptedBallot (0,0), acceptedValue None)) 47 | (2 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Promise(promisedBallot (2,3), acceptedBallot (0,0), acceptedValue None)) 48 | (2 -> 4) triggering PL_Send(TAddress(/192.168.2.1:1000), Promise(promisedBallot (3,1), acceptedBallot (0,0), acceptedValue None)) 49 | (1 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Accepted(acceptBallot Accept((2,2),-962504004).acceptBallot)) 50 | (3 -> 4) triggering PL_Send(TAddress(/192.168.2.1:1000), Promise(promisedBallot (3,1), acceptedBallot (2,2), acceptedValue Some(-962504004))) 51 | (3 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Nack(acceptBallot Accept((2,2),-962504004).acceptBallot)) 52 | (1 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Accepted(acceptBallot Accept((2,2),-962504004).acceptBallot)) 53 | (4 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Nack(acceptBallot Accept((2,2),-962504004).acceptBallot)) 54 | (4 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Nack(acceptBallot Accept((2,2),-962504004).acceptBallot)) 55 | (2 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Nack(acceptBallot Accept((2,2),-962504004).acceptBallot)) 56 | (1 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Promise(promisedBallot (2,3), acceptedBallot (2,2), acceptedValue Some(-962504004))) 57 | (3 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Nack(prep.proposalBallot Prepare((2,3)).proposalBallot)) 58 | (2 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Nack(acceptBallot Accept((2,2),-962504004).acceptBallot)) 59 | (1 -> 4) triggering PL_Send(TAddress(/192.168.2.1:1000), Promise(promisedBallot (3,1), acceptedBallot (2,2), acceptedValue Some(-962504004))) 60 | (4 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Nack(prep.proposalBallot Prepare((2,3)).proposalBallot)) 61 | (2 -> 4) triggering BEB_Broadcast(Decided(proposedValue Some(-962504004))) 62 | (2 -> 4) triggering BEB_Broadcast(Prepare(round 3, rank 2)) 63 | (1 -> 4) triggering BEB_Broadcast(Accept((round 3, rank 1), proposedValue Some(-962504004))) 64 | (3 -> 4) triggering BEB_Broadcast(Prepare(round 3, rank 3)) 65 | (1 -> 4) triggering BEB_Broadcast(Accept((round 3, rank 1), proposedValue Some(-962504004))) 66 | (2 -> 4) triggering Decided(dec.decidedValue Decided(Some(-962504004)).decidedValue) 67 | (3 -> 4) triggering Decided(dec.decidedValue Decided(Some(-962504004)).decidedValue) 68 | (1 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Promise(promisedBallot (3,2), acceptedBallot (2,2), acceptedValue Some(-962504004))) 69 | (3 -> 4) triggering PL_Send(TAddress(/192.168.2.1:1000), Accepted(acceptBallot Accept((3,1),-962504004).acceptBallot)) 70 | (1 -> 4) triggering PL_Send(TAddress(/192.168.2.1:1000), Nack(acceptBallot Accept((3,1),-962504004).acceptBallot)) 71 | (1 -> 4) triggering Decided(dec.decidedValue Decided(Some(-962504004)).decidedValue) 72 | (1 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Promise(promisedBallot (3,3), acceptedBallot (2,2), acceptedValue Some(-962504004))) 73 | (4 -> 4) triggering Decided(dec.decidedValue Decided(Some(-962504004)).decidedValue) 74 | (3 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Promise(promisedBallot (3,2), acceptedBallot (3,1), acceptedValue Some(-962504004))) 75 | (3 -> 4) triggering PL_Send(TAddress(/192.168.2.1:1000), Nack(acceptBallot Accept((3,1),-962504004).acceptBallot)) 76 | (4 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Promise(promisedBallot (3,2), acceptedBallot (0,0), acceptedValue None)) 77 | (2 -> 4) triggering PL_Send(TAddress(/192.168.2.1:1000), Accepted(acceptBallot Accept((3,1),-962504004).acceptBallot)) 78 | (4 -> 4) triggering PL_Send(TAddress(/192.168.2.1:1000), Nack(acceptBallot Accept((3,1),-962504004).acceptBallot)) 79 | (2 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Promise(promisedBallot (3,2), acceptedBallot (3,1), acceptedValue Some(-962504004))) 80 | (3 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Promise(promisedBallot (3,3), acceptedBallot (3,1), acceptedValue Some(-962504004))) 81 | (4 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Promise(promisedBallot (3,3), acceptedBallot (0,0), acceptedValue None)) 82 | (1 -> 4) triggering PL_Send(TAddress(/192.168.2.1:1000), Nack(acceptBallot Accept((3,1),-962504004).acceptBallot)) 83 | (2 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Promise(promisedBallot (3,3), acceptedBallot (3,1), acceptedValue Some(-962504004))) 84 | (4 -> 4) triggering PL_Send(TAddress(/192.168.2.1:1000), Nack(acceptBallot Accept((3,1),-962504004).acceptBallot)) 85 | (2 -> 4) triggering PL_Send(TAddress(/192.168.2.1:1000), Nack(acceptBallot Accept((3,1),-962504004).acceptBallot)) 86 | (2 -> 4) triggering BEB_Broadcast(Accept((round 3, rank 2), proposedValue Some(-962504004))) 87 | (2 -> 4) triggering BEB_Broadcast(Accept((round 3, rank 2), proposedValue Some(-962504004))) 88 | (1 -> 4) triggering BEB_Broadcast(Decided(proposedValue Some(-962504004))) 89 | (3 -> 4) triggering BEB_Broadcast(Accept((round 3, rank 3), proposedValue Some(-962504004))) 90 | (2 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Nack(acceptBallot Accept((3,2),-962504004).acceptBallot)) 91 | (1 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Nack(acceptBallot Accept((3,2),-962504004).acceptBallot)) 92 | (1 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Nack(acceptBallot Accept((3,2),-962504004).acceptBallot)) 93 | (4 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Nack(acceptBallot Accept((3,2),-962504004).acceptBallot)) 94 | (3 -> 4) triggering BEB_Broadcast(Accept((round 3, rank 3), proposedValue Some(-962504004))) 95 | (3 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Nack(acceptBallot Accept((3,2),-962504004).acceptBallot)) 96 | (3 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Nack(acceptBallot Accept((3,2),-962504004).acceptBallot)) 97 | (1 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Accepted(acceptBallot Accept((3,3),-962504004).acceptBallot)) 98 | (2 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Nack(acceptBallot Accept((3,2),-962504004).acceptBallot)) 99 | (4 -> 4) triggering PL_Send(TAddress(/192.168.2.2:1000), Nack(acceptBallot Accept((3,2),-962504004).acceptBallot)) 100 | (3 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Accepted(acceptBallot Accept((3,3),-962504004).acceptBallot)) 101 | (2 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Accepted(acceptBallot Accept((3,3),-962504004).acceptBallot)) 102 | (3 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Accepted(acceptBallot Accept((3,3),-962504004).acceptBallot)) 103 | (2 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Accepted(acceptBallot Accept((3,3),-962504004).acceptBallot)) 104 | (4 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Accepted(acceptBallot Accept((3,3),-962504004).acceptBallot)) 105 | (4 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Accepted(acceptBallot Accept((3,3),-962504004).acceptBallot)) 106 | (1 -> 4) triggering PL_Send(TAddress(/192.168.2.3:1000), Accepted(acceptBallot Accept((3,3),-962504004).acceptBallot)) 107 | (3 -> 4) triggering BEB_Broadcast(Decided(proposedValue Some(-962504004))) -------------------------------------------------------------------------------- /Distributed Consensus/Exercise-Consensus.md: -------------------------------------------------------------------------------- 1 | ### Assignment 4: Distributed Consensus ### 2 | 3 | In this final programming assignment for Part I of the course you will have to complete the implementation of a variation of the famous Paxos algorithm. 4 | 5 | When you are done you simply have to export your notebook and then upload it in the "Programming Exercise 5" page. 6 | 7 | **Things to Remember**: 8 | 1. Basic components such as `PerfectLink` and `Best-Effort Broadcast` are already provided. No need to implement them. 9 | 2. Execute the imports defined below **before** compiling your component implementations. 10 | 3. We recommend making use of the component state and internal messages we have provided, if any, to complete the implementation logic. 11 | 4. You can always print messages to the output log, from within handlers to see what happens during the simulation. e.g. `println(s"Process $self delivers message $msg");` 12 | 5. Remember that during the simulation check you can print and observe the simulation time, i.e. with `System.currentTimeMillis()`. 13 | 5. Do not forget to run the checker code block after each component implementation to ensure that all properties are satisfied **before** exporting and submitting the notebook. 14 | 6. You can always restart the Kompics Interpreter to start fresh (Interpreter→KompicsInterpreter→Click Restart) 15 | 16 | Good luck! :) 17 | 18 | 19 | ## Leader-less Obstraction-Free Paxos for Single Value Consensus ## 20 | 21 | A (single value) Consensus Abstraction, in Kompics terms, is a component that **provides** the following port *(already imported in the notebook)*. 22 | ```scala 23 | class Consensus extends Port{ 24 | request[C_Propose]; 25 | indication[C_Decide]; 26 | } 27 | ``` 28 | An **Consensus** component should request value proposals (`C_Propose`) and respond with decided value events (`C_Decide`) respectively as defined below: 29 | ```scala 30 | case class C_Decide(value: Any) extends KompicsEvent; 31 | case class C_Propose(value: Any) extends KompicsEvent; 32 | ``` 33 | The following properties define the expected behavior of a consensus abstraction more specifically: 34 | 35 | 1. **Validity**: *Only proposed values may be decided.* 36 | 2. **Uniform Agreement**: *No two nodes decide different values.* 37 | 3. **Integrity**: *Each node can decide a value at most once.* 38 | 4. **Termination**: *Every node eventually decides a value.* 39 | 40 | The recommended algorithm to use is the the one we call "Leaderless Repeatable Paxos" which initiates new proposal rounds until a decision has been made. 41 | -------------------------------------------------------------------------------- /Distributed Consensus/Exercise-Consensus.scala: -------------------------------------------------------------------------------- 1 | import se.kth.edx.id2203.core.ExercisePrimitives.AddressUtils._ 2 | import se.kth.edx.id2203.core.Ports._ 3 | import se.kth.edx.id2203.validation._ 4 | import se.sics.kompics.network._ 5 | import se.sics.kompics.sl.{Init, _} 6 | import se.sics.kompics.{KompicsEvent, ComponentDefinition => _, Port => _} 7 | import scala.language.implicitConversions 8 | import scala.collection.mutable.ListBuffer; 9 | 10 | import se.sics.kompics.timer.{ScheduleTimeout, Timeout, Timer} 11 | 12 | case class Prepare(proposalBallot: (Int, Int)) extends KompicsEvent; 13 | case class Promise(promiseBallot: (Int, Int), acceptedBallot: (Int, Int), acceptedValue: Option[Any]) extends KompicsEvent; 14 | case class Accept(acceptBallot: (Int, Int), proposedValue: Any) extends KompicsEvent; 15 | case class Accepted(acceptedBallot: (Int, Int)) extends KompicsEvent; 16 | case class Nack(ballot: (Int, Int)) extends KompicsEvent; 17 | case class Decided(decidedValue: Any) extends KompicsEvent; 18 | 19 | /** 20 | * This augments tuples with comparison operators implicitly, which you can use in your code, for convenience. 21 | * examples: (1,2) > (1,4) yields 'false' and (5,4) <= (7,4) yields 'true' 22 | */ 23 | implicit def addComparators[A](x: A)(implicit o: math.Ordering[A]): o.Ops = o.mkOrderingOps(x); 24 | 25 | //HINT: After you execute the latter implicit ordering you can compare tuples as such within your component implementation: 26 | (1,2) <= (1,4); 27 | 28 | 29 | class Paxos(paxosInit: Init[Paxos]) extends ComponentDefinition { 30 | 31 | //Port Subscriptions for Paxos 32 | 33 | val consensus = provides[Consensus]; 34 | val beb = requires[BestEffortBroadcast]; 35 | val plink = requires[PerfectLink]; 36 | 37 | //Internal State of Paxos 38 | val (rank, numProcesses) = paxosInit match { 39 | case Init(s: Address, qSize: Int) => (toRank(s), qSize) 40 | } 41 | 42 | //Proposer State 43 | var round = 0; 44 | var proposedValue: Option[Any] = None; 45 | var promises: ListBuffer[((Int, Int), Option[Any])] = ListBuffer.empty; 46 | var numOfAccepts = 0; 47 | var decided = false; 48 | 49 | //Acceptor State 50 | var promisedBallot = (0, 0); 51 | var acceptedBallot = (0, 0); 52 | var acceptedValue: Option[Any] = None; 53 | 54 | def propose() = { 55 | if(!decided){ 56 | round = round + 1; 57 | numOfAccepts = 0; 58 | promises = ListBuffer.empty; 59 | println(s"($rank -> $numProcesses) triggering BEB_Broadcast(Prepare(round $round, rank $rank))"); 60 | trigger(BEB_Broadcast(Prepare(round,rank)) -> beb); 61 | } 62 | } 63 | 64 | consensus uponEvent { 65 | case C_Propose(value) => handle { 66 | proposedValue = Some(value); 67 | propose(); 68 | } 69 | } 70 | 71 | 72 | beb uponEvent { 73 | 74 | case BEB_Deliver(src, prep: Prepare) => handle { 75 | if(promisedBallot < prep.proposalBallot){ 76 | promisedBallot = prep.proposalBallot; 77 | println(s"($rank -> $numProcesses) triggering PL_Send($src, Promise(promisedBallot $promisedBallot, acceptedBallot $acceptedBallot, acceptedValue $acceptedValue))"); 78 | trigger(PL_Send(src, Promise(promisedBallot, acceptedBallot, acceptedValue))-> plink); 79 | } else { 80 | println(s"($rank -> $numProcesses) triggering PL_Send($src, Nack(prep.proposalBallot $prep.proposalBallot))"); 81 | trigger(PL_Send(src, Nack(prep.proposalBallot))-> plink); 82 | } 83 | }; 84 | 85 | case BEB_Deliver(src, acc: Accept) => handle { 86 | if(promisedBallot <= acc.acceptBallot){ 87 | acceptedBallot = acc.acceptBallot; 88 | promisedBallot = acceptedBallot; 89 | acceptedValue = Some(acc.proposedValue); 90 | println(s"($rank -> $numProcesses) triggering PL_Send($src, Accepted(acceptBallot $acc.acceptBallot))"); 91 | trigger(PL_Send(src, Accepted(acc.acceptBallot))-> plink); 92 | } else { 93 | println(s"($rank -> $numProcesses) triggering PL_Send($src, Nack(acceptBallot $acc.acceptBallot))"); 94 | trigger(PL_Send(src, Nack(acc.acceptBallot))-> plink); 95 | } 96 | }; 97 | 98 | case BEB_Deliver(src, dec : Decided) => handle { 99 | if(!decided){ 100 | println(s"($rank -> $numProcesses) triggering Decided(dec.decidedValue $dec.decidedValue)"); 101 | trigger(C_Decide(dec.decidedValue) -> consensus); 102 | decided = true; 103 | } 104 | } 105 | } 106 | 107 | plink uponEvent { 108 | 109 | case PL_Deliver(src, prepAck: Promise) => handle { 110 | if ((round, rank) == prepAck.promiseBallot) { 111 | promises += ((prepAck.acceptedBallot, prepAck.acceptedValue)); 112 | if(promises.size > (numProcesses + 1) / 2){ 113 | var (maxBallot, value) = promises.maxBy { case (key, value) => key }; 114 | if (value.isDefined) { 115 | proposedValue = value 116 | } 117 | println(s"($rank -> $numProcesses) triggering BEB_Broadcast(Accept((round $round, rank $rank), proposedValue $proposedValue))"); 118 | trigger(BEB_Broadcast(Accept((round, rank), proposedValue.get)) -> beb); 119 | } 120 | } 121 | }; 122 | 123 | case PL_Deliver(src, accAck: Accepted) => handle { 124 | if ((round, rank) == accAck.acceptedBallot) { 125 | numOfAccepts = numOfAccepts + 1; 126 | if(numOfAccepts == (numProcesses + 1) / 2){ 127 | println(s"($rank -> $numProcesses) triggering BEB_Broadcast(Decided(proposedValue $proposedValue))"); 128 | trigger(BEB_Broadcast(Decided(proposedValue)) -> beb); 129 | } 130 | } 131 | }; 132 | 133 | case PL_Deliver(src, nack: Nack) => handle { 134 | if ((round, rank) == nack.ballot) { 135 | propose() 136 | } 137 | } 138 | } 139 | 140 | 141 | }; -------------------------------------------------------------------------------- /Eventually Perfect Failure Detector/EventuallyPerfectFailureDetector.json: -------------------------------------------------------------------------------- 1 | {"paragraphs":[{"text":"%md\n\n### Exercise 1: Build an Eventually Perfect Failure Detector\n\nAn Eventually Perfect Failure Detector (EPFD), in Kompics terms, is a component that **provides** the following port *(already imported in the notebook)*.\n\n class EventuallyPerfectFailureDetector extends Port {\n indication[Suspect];\n indication[Restore];\n }\n\nSimply put, your component should indicate or 'deliver' to the application the following messages:\n\n case class Suspect(src: Address) extends KompicsEvent;\n case class Restore(src: Address) extends KompicsEvent;\n\nAs you have already learnt from the course lectures, an EPFD, defined in a partially synchronous model, should satisfy the following properties:\n\n1. **Completeness**: Every process that crashes should be eventually suspected permanently by every correct process\n2. **Eventual Strong Accuracy**: No correct process should be eventually suspected by any other correct process\n \nTo complete this assignment you will have to fill in the missing functionality denoted by the commented sections below and pass the property checking test at the end of this notebook.\nThe recommended algorithm to use in this assignment is *EPFD with Increasing Timeout and Sequence Numbers*, which you can find at the second page of this [document](https://courses.edx.org/asset-v1:KTHx+ID2203.1x+2016T3+type@asset+block@epfd.pdf) in the respective lecture.\n\n\n","dateUpdated":"2017-12-19T12:59:47+0000","config":{"editorSetting":{},"editorMode":"ace/mode/markdown","colWidth":12,"editorHide":true,"fontSize":9,"results":[{"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}}],"enabled":true},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"
\n

Exercise 1: Build an Eventually Perfect Failure Detector

\n

An Eventually Perfect Failure Detector (EPFD), in Kompics terms, is a component that provides the following port (already imported in the notebook).

\n
class EventuallyPerfectFailureDetector extends Port {\n indication[Suspect];\n indication[Restore];\n}\n
\n

Simply put, your component should indicate or ‘deliver’ to the application the following messages:

\n
case class Suspect(src: Address) extends KompicsEvent;\ncase class Restore(src: Address) extends KompicsEvent;\n
\n

As you have already learnt from the course lectures, an EPFD, defined in a partially synchronous model, should satisfy the following properties:

\n
    \n
  1. Completeness: Every process that crashes should be eventually suspected permanently by every correct process
  2. \n
  3. Eventual Strong Accuracy: No correct process should be eventually suspected by any other correct process
  4. \n
\n

To complete this assignment you will have to fill in the missing functionality denoted by the commented sections below and pass the property checking test at the end of this notebook.
The recommended algorithm to use in this assignment is EPFD with Increasing Timeout and Sequence Numbers, which you can find at the second page of this document in the respective lecture.

\n
"}]},"apps":[],"jobName":"paragraph_1513688387725_1534753103","id":"20160909-160459_701472878","dateCreated":"2017-12-19T12:59:47+0000","status":"READY","errorMessage":"","progressUpdateIntervalMs":500,"focus":true,"$$hashKey":"object:96"},{"text":"import se.kth.edx.id2203.core.Ports._\nimport se.kth.edx.id2203.validation._\nimport se.sics.kompics.network._\nimport se.sics.kompics.sl.{Init, _}\nimport se.sics.kompics.timer.{ScheduleTimeout, Timeout, Timer}\nimport se.sics.kompics.{KompicsEvent, Start, ComponentDefinition => _, Port => _}","dateUpdated":"2017-12-19T12:59:47+0000","config":{"editorSetting":{"language":"scala","editOnDblClick":false},"editorMode":"ace/mode/scala","colWidth":12,"editorHide":false,"fontSize":9,"results":{},"enabled":true,"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1513688387732_1544371826","id":"20160623-152816_923395673","dateCreated":"2017-12-19T12:59:47+0000","status":"READY","errorMessage":"","progressUpdateIntervalMs":500,"$$hashKey":"object:97"},{"text":" //Custom messages to be used in the internal component implementation\n case class CheckTimeout(timeout: ScheduleTimeout) extends Timeout(timeout);\n\n case class HeartbeatReply(seq: Int) extends KompicsEvent;\n case class HeartbeatRequest(seq: Int) extends KompicsEvent;","dateUpdated":"2017-12-19T12:59:47+0000","config":{"editorSetting":{"language":"scala","editOnDblClick":false},"editorMode":"ace/mode/scala","colWidth":12,"fontSize":9,"results":{},"enabled":true,"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1513688387733_1543987077","id":"20160830-153841_517626554","dateCreated":"2017-12-19T12:59:47+0000","status":"READY","errorMessage":"","progressUpdateIntervalMs":500,"$$hashKey":"object:98"},{"text":"\n//Define EPFD Implementation\nclass EPFD(epfdInit: Init[EPFD]) extends ComponentDefinition {\n\n //EPFD subscriptions\n val timer = requires[Timer];\n val pLink = requires[PerfectLink];\n val epfd = provides[EventuallyPerfectFailureDetector];\n\n // EPDF component state and initialization\n \n //configuration parameters\n val self = epfdInit match {case Init(s: Address) => s};\n val topology = cfg.getValue[List[Address]](\"epfd.simulation.topology\");\n val delta = cfg.getValue[Long](\"epfd.simulation.delay\");\n \n //mutable state\n var period = cfg.getValue[Long](\"epfd.simulation.delay\");\n var alive = Set(cfg.getValue[List[Address]](\"epfd.simulation.topology\"): _*);\n var suspected = Set[Address]();\n var seqnum = 0;\n\n def startTimer(delay: Long): Unit = {\n val scheduledTimeout = new ScheduleTimeout(period);\n scheduledTimeout.setTimeoutEvent(CheckTimeout(scheduledTimeout));\n trigger(scheduledTimeout -> timer);\n }\n\n //EPFD event handlers\n ctrl uponEvent {\n case _: Start => handle {\n period = cfg.getValue[Long](\"epfd.simulation.delay\");\n alive = Set(cfg.getValue[List[Address]](\"epfd.simulation.topology\"): _*);\n suspected = Set[Address]();\n seqnum = 0;\n startTimer(period);\n }\n }\n\n timer uponEvent {\n case CheckTimeout(_) => handle {\n if (!alive.intersect(suspected).isEmpty) {\n \n period = period + delta;\n \n }\n \n seqnum = seqnum + 1;\n \n for (p <- topology) {\n if (!alive.contains(p) && !suspected.contains(p)) {\n \n suspected = suspected + p;\n trigger(Suspect(p) -> epfd);\n \n } else if (alive.contains(p) && suspected.contains(p)) {\n suspected = suspected - p;\n trigger(Restore(p) -> epfd);\n }\n trigger(PL_Send(p, HeartbeatRequest(seqnum)) -> pLink);\n }\n alive = Set[Address]();\n startTimer(period);\n }\n }\n\n pLink uponEvent {\n case PL_Deliver(src, HeartbeatRequest(seq)) => handle {\n\n trigger(PL_Send(src, HeartbeatRequest(seq)) -> pLink);\n \n }\n case PL_Deliver(src, HeartbeatReply(seq)) => handle {\n\n if(seq == seqnum || suspected.contains(src)){\n alive = alive + src;\n }\n \n }\n }\n};\n\n\n","dateUpdated":"2017-12-19T13:19:31+0000","config":{"lineNumbers":true,"editorSetting":{"language":"scala","editOnDblClick":false},"editorMode":"ace/mode/scala","colWidth":12,"fontSize":9,"results":{},"enabled":true,"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1513688387733_1543987077","id":"20160728-151056_2139297732","dateCreated":"2017-12-19T12:59:47+0000","status":"FINISHED","progressUpdateIntervalMs":500,"$$hashKey":"object:99","user":"anonymous","dateFinished":"2017-12-19T13:19:32+0000","dateStarted":"2017-12-19T13:19:31+0000","results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"defined class EPFD
"}]}},{"text":"checkEPFD[EPFD]","dateUpdated":"2017-12-19T13:19:35+0000","config":{"editorSetting":{"language":"scala","editOnDblClick":false},"editorMode":"ace/mode/scala","colWidth":12,"fontSize":9,"results":{},"enabled":true,"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1513688387733_1543987077","id":"20160704-003955_2062490082","dateCreated":"2017-12-19T12:59:47+0000","status":"FINISHED","progressUpdateIntervalMs":500,"$$hashKey":"object:100","user":"anonymous","dateFinished":"2017-12-19T13:24:18+0000","dateStarted":"2017-12-19T13:19:35+0000","results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"
Your submission has been locally simulated and validated.

Click Here to view the output of the simulation.



Correction Results
PASSED Strong Completeness ✔: Every process that crashes is eventually suspected permanently by every correct process
PASSED Eventual Strong Accuracy ✔: Eventually, no correct process is suspected by any correct process

Final Comments
**************
Congratulations! Your implementation of the 'Eventually Perfect Failure Detector' satisfies all properties!
A unique token has been generated for your submission right below. Please do not edit.

{\"gradingToken\":[45,45,45,45,45,66,69,71,73,78,32,80,71,80,32,77,69,83,83,65,71,69,45,45,45,45,45,10,86,101,114,115,105,111,110,58,32,66,67,80,71,32,118,49,46,53,53,10,10,104,81,73,77,65,57,79,116,77,118,84,69,98,74,49,102,65,81,47,56,68,56,89,78,109,75,105,99,101,116,78,110,87,117,53,111,57,120,105,101,47,103,119,55,48,100,90,120,74,122,88,119,112,99,49,112,80,98,70,104,65,117,104,79,10,107,73,79,102,107,120,79,98,87,99,101,67,56,79,75,75,71,117,57,75,47,115,82,105,100,89,81,100,47,117,49,48,116,118,112,50,80,83,106,75,76,84,103,100,113,74,90,76,103,43,103,83,67,84,82,122,84,104,51,76,55,65,106,76,10,56,77,98,68,78,68,50,105,48,115,80,78,69,97,57,48,73,108,109,67,119,70,120,50,122,105,102,50,78,101,50,81,105,79,90,43,110,72,74,98,104,54,85,119,111,104,109,67,74,121,55,86,48,82,114,114,57,81,120,114,108,111,47,99,10,98,87,98,120,120,97,106,77,47,84,111,113,49,56,57,100,78,108,68,51,80,78,84,79,122,65,50,81,83,118,98,111,54,110,74,79,65,97,52,77,53,89,97,53,117,109,75,43,74,89,88,79,101,119,72,71,65,54,106,115,77,109,120,57,10,65,118,89,120,106,89,53,76,78,107,119,105,86,76,118,73,88,109,75,55,51,81,115,97,113,68,78,101,87,120,76,121,110,98,102,69,54,54,65,57,100,76,106,117,80,107,53,114,83,67,102,88,101,43,86,86,66,53,57,109,68,115,101,113,10,86,53,84,103,98,111,112,116,76,87,73,103,122,98,88,114,66,120,74,98,74,68,71,53,115,120,112,116,97,43,66,57,86,80,74,53,111,68,78,75,103,114,121,108,72,100,50,48,43,122,115,111,56,111,90,101,68,74,71,100,49,90,73,49,10,110,112,79,116,105,110,67,53,50,48,54,73,107,72,57,54,54,68,101,116,75,109,75,72,112,51,72,87,90,43,87,54,52,111,74,86,114,100,101,47,101,73,84,89,86,114,55,108,65,114,49,71,75,78,53,117,88,55,73,51,122,56,48,49,10,107,88,114,81,79,108,114,69,49,84,120,75,120,109,78,73,117,102,69,108,73,103,86,80,73,53,78,83,79,103,54,103,84,88,49,105,97,97,75,102,97,81,85,101,71,105,122,55,98,97,50,102,77,65,69,78,77,83,90,79,97,80,80,107,10,85,120,90,122,79,43,72,118,78,109,49,68,103,116,73,49,57,43,115,50,102,53,50,97,78,55,102,69,103,75,113,79,86,68,75,75,51,69,99,77,121,110,49,82,118,69,73,98,55,75,110,103,57,114,119,79,81,73,68,70,89,101,66,48,10,81,101,84,90,106,121,119,116,51,81,116,57,121,83,49,47,55,122,75,99,52,90,100,105,120,119,80,80,90,114,103,113,79,77,50,55,51,89,111,76,105,117,120,87,66,102,106,79,88,109,65,107,90,112,100,84,67,86,121,121,101,43,69,103,10,110,118,116,106,77,48,103,76,66,80,74,85,105,47,79,79,49,116,70,110,81,87,108,85,43,85,121,98,43,75,48,73,113,70,76,104,109,115,79,118,71,90,78,72,77,48,43,56,113,106,112,99,76,66,115,80,53,47,104,79,114,113,47,83,10,119,67,81,66,47,88,98,108,105,108,84,113,105,88,82,47,69,122,72,85,85,49,70,105,66,87,100,69,112,52,116,75,47,65,88,107,49,52,88,50,52,85,78,48,108,54,67,89,48,116,79,79,79,65,112,112,50,74,54,110,65,98,102,50,10,84,90,112,112,113,83,48,115,55,120,81,101,52,85,114,107,121,97,97,104,81,103,55,87,51,106,48,118,53,90,57,76,106,65,48,108,81,48,73,122,112,80,53,116,98,114,50,103,89,76,90,109,78,112,115,80,80,68,86,85,81,97,82,51,10,47,99,104,87,49,97,80,71,97,119,109,112,114,115,76,88,89,47,66,66,98,114,68,88,54,43,57,114,51,86,111,107,105,111,71,114,71,106,43,97,102,109,108,117,49,74,65,122,101,72,51,78,106,116,77,43,85,56,90,52,78,109,109,70,10,76,79,103,119,66,122,52,66,108,110,53,66,74,80,76,97,88,50,71,107,74,107,57,109,107,81,73,87,77,114,72,52,65,97,54,122,119,118,110,57,108,79,82,119,115,47,98,43,89,89,104,89,115,53,43,65,75,73,50,69,47,56,105,118,10,98,51,49,78,53,51,117,106,56,88,76,109,119,87,102,71,121,49,79,66,101,48,55,69,106,55,52,87,103,49,53,120,57,51,101,105,114,53,85,81,43,109,108,111,48,119,65,50,89,87,56,61,10,61,102,75,120,121,10,45,45,45,45,45,69,78,68,32,80,71,80,32,77,69,83,83,65,71,69,45,45,45,45,45,10]}
res24: Boolean = true
"}]}},{"text":"","dateUpdated":"2017-12-19T12:59:47+0000","config":{"editorSetting":{"language":"scala","editOnDblClick":false},"editorMode":"ace/mode/scala","colWidth":12,"fontSize":9,"results":{},"enabled":true,"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1513688387751_1526288627","id":"20160728-143652_1894660652","dateCreated":"2017-12-19T12:59:47+0000","status":"READY","errorMessage":"","progressUpdateIntervalMs":500,"$$hashKey":"object:101"}],"name":"Exercise 1","id":"2D4R7T8AP","angularObjects":{"2BKQCVH92:shared_process":[],"2CVXXPNWV:shared_process":[]},"config":{"looknfeel":"default","personalizedMode":"false"},"info":{}} -------------------------------------------------------------------------------- /Eventually Perfect Failure Detector/EventuallyPerfectFailureDetector.md: -------------------------------------------------------------------------------- 1 | ### Assignment 1: Build an Eventually Perfect Failure Detector ### 2 | An Eventually Perfect Failure Detector (EPFD), in Kompics terms, is a component that provides the following port (already imported in the notebook). 3 | ```scala 4 | class EventuallyPerfectFailureDetector extends Port { 5 | indication[Suspect]; 6 | indication[Restore]; 7 | } 8 | ``` 9 | Simply put, your component should indicate or ‘deliver’ to the application the following messages: 10 | ```scala 11 | case class Suspect(src: Address) extends KompicsEvent; 12 | case class Restore(src: Address) extends KompicsEvent; 13 | ``` 14 | As you have already learnt from the course lectures, an EPFD, defined in a partially synchronous model, should satisfy the following properties: 15 | 16 | - __Completeness__: Every process that crashes should be eventually suspected permanently by every correct process 17 | - __Eventual Strong Accuracy__: No correct process should be eventually suspected by any other correct process 18 | To complete this assignment you will have to fill in the missing functionality denoted by the commented sections below and pass the property checking test at the end of this notebook. -------------------------------------------------------------------------------- /Eventually Perfect Failure Detector/EventuallyPerfectFailureDetector.scala: -------------------------------------------------------------------------------- 1 | import se.kth.edx.id2203.core.Ports._ 2 | import se.kth.edx.id2203.validation._ 3 | import se.sics.kompics.network._ 4 | import se.sics.kompics.sl.{Init, _} 5 | import se.sics.kompics.timer.{ScheduleTimeout, Timeout, Timer} 6 | import se.sics.kompics.{KompicsEvent, Start, ComponentDefinition => _, Port => _} 7 | 8 | //Custom messages to be used in the internal component implementation 9 | case class CheckTimeout(timeout: ScheduleTimeout) extends Timeout(timeout); 10 | 11 | case class HeartbeatReply(seq: Int) extends KompicsEvent; 12 | case class HeartbeatRequest(seq: Int) extends KompicsEvent; 13 | 14 | //Define EPFD Implementation 15 | class EPFD(epfdInit: Init[EPFD]) extends ComponentDefinition { 16 | 17 | //EPFD subscriptions 18 | val timer = requires[Timer]; 19 | val pLink = requires[PerfectLink]; 20 | val epfd = provides[EventuallyPerfectFailureDetector]; 21 | 22 | // EPDF component state and initialization 23 | 24 | //configuration parameters 25 | val self = epfdInit match {case Init(s: Address) => s}; 26 | val topology = cfg.getValue[List[Address]]("epfd.simulation.topology"); 27 | val delta = cfg.getValue[Long]("epfd.simulation.delay"); 28 | 29 | //mutable state 30 | var period = cfg.getValue[Long]("epfd.simulation.delay"); 31 | var alive = Set(cfg.getValue[List[Address]]("epfd.simulation.topology"): _*); 32 | var suspected = Set[Address](); 33 | var seqnum = 0; 34 | 35 | def startTimer(delay: Long): Unit = { 36 | val scheduledTimeout = new ScheduleTimeout(period); 37 | scheduledTimeout.setTimeoutEvent(CheckTimeout(scheduledTimeout)); 38 | trigger(scheduledTimeout -> timer); 39 | } 40 | 41 | //EPFD event handlers 42 | ctrl uponEvent { 43 | case _: Start => handle { 44 | period = cfg.getValue[Long]("epfd.simulation.delay"); 45 | alive = Set(cfg.getValue[List[Address]]("epfd.simulation.topology"): _*); 46 | suspected = Set[Address](); 47 | seqnum = 0; 48 | startTimer(period); 49 | } 50 | } 51 | 52 | timer uponEvent { 53 | case CheckTimeout(_) => handle { 54 | if (!alive.intersect(suspected).isEmpty) { 55 | 56 | period = period + delta; 57 | 58 | } 59 | 60 | seqnum = seqnum + 1; 61 | 62 | for (p <- topology) { 63 | if (!alive.contains(p) && !suspected.contains(p)) { 64 | 65 | suspected = suspected + p; 66 | trigger(Suspect(p) -> epfd); 67 | 68 | } else if (alive.contains(p) && suspected.contains(p)) { 69 | suspected = suspected - p; 70 | trigger(Restore(p) -> epfd); 71 | } 72 | trigger(PL_Send(p, HeartbeatRequest(seqnum)) -> pLink); 73 | } 74 | alive = Set[Address](); 75 | startTimer(period); 76 | } 77 | } 78 | 79 | pLink uponEvent { 80 | case PL_Deliver(src, HeartbeatRequest(seq)) => handle { 81 | 82 | trigger(PL_Send(src, HeartbeatRequest(seq)) -> pLink); 83 | 84 | } 85 | case PL_Deliver(src, HeartbeatReply(seq)) => handle { 86 | 87 | if(seq == seqnum || suspected.contains(src)){ 88 | alive = alive + src; 89 | } 90 | 91 | } 92 | } 93 | }; -------------------------------------------------------------------------------- /Exercise Broadcast Abstractions/Exercise-_Broadcast_Abstractions.json: -------------------------------------------------------------------------------- 1 | {"paragraphs":[{"text":"%md\n\n### From Best Effort to Causal Order Reliable Broadcast\n\nThis is the first programming assignment where you will have to build and reuse multiple components. \nStarting bottom-up, you will first have to implement *best effort broadcast*, then *reliable broadcast* and finally *causal order reliable broadcast*.\nMind that passing each component check will give you a **partial** grade and therefore you will need to pass **all** checks to get the full grade for this programming assignment.\n\n**Things to Remember**:\n1. Some components such as `PerfectLink`, `Network` and `Timer` are already provided. No need to implement them.\n2. Execute the imports defined below **before** compiling your component implementations.\n3. We recommend making use of the component state and internal messages we have provided, if any, to complete the implementation logic.\n4. You can always print messages to the output log, from within handlers to see what happens during the simulation. e.g. `println(s\"Process $self delivers message $msg\");`\n5. Remember that during the simulation check you can print and observe the simulation time, i.e. with `System.currentTimeMillis()`.\n5. Do not forget to run the checker code block after each component implementation to ensure that all properties are satisfied before exporting and submitting the notebook.\n6. You can always restart the Kompics Interpreter to start fresh (Interpreter→KompicsInterpreter→Click Restart)\n7. Do **not** submit just the grading token to edx. You will have to submit the whole exported notebook content to get your grade.\n\nGood luck! :)","dateUpdated":"2017-12-24T15:46:43+0000","config":{"editorSetting":{},"editorMode":"ace/mode/scala","colWidth":12,"editorHide":true,"fontSize":9,"results":[{"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}}],"enabled":true},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"
\n

From Best Effort to Causal Order Reliable Broadcast

\n

This is the first programming assignment where you will have to build and reuse multiple components.
Starting bottom-up, you will first have to implement best effort broadcast, then reliable broadcast and finally causal order reliable broadcast.
Mind that passing each component check will give you a partial grade and therefore you will need to pass all checks to get the full grade for this programming assignment.

\n

Things to Remember:
1. Some components such as PerfectLink, Network and Timer are already provided. No need to implement them.
2. Execute the imports defined below before compiling your component implementations.
3. We recommend making use of the component state and internal messages we have provided, if any, to complete the implementation logic.
4. You can always print messages to the output log, from within handlers to see what happens during the simulation. e.g. println(s"Process $self delivers message $msg");
5. Remember that during the simulation check you can print and observe the simulation time, i.e. with System.currentTimeMillis().
5. Do not forget to run the checker code block after each component implementation to ensure that all properties are satisfied before exporting and submitting the notebook.
6. You can always restart the Kompics Interpreter to start fresh (Interpreter→KompicsInterpreter→Click Restart)
7. Do not submit just the grading token to edx. You will have to submit the whole exported notebook content to get your grade.

\n

Good luck! :)

\n
"}]},"apps":[],"jobName":"paragraph_1514130403309_393131195","id":"20160915-144724_1712226433","dateCreated":"2017-12-24T15:46:43+0000","status":"READY","errorMessage":"","progressUpdateIntervalMs":500,"focus":true,"$$hashKey":"object:6716"},{"text":"import se.kth.edx.id2203.core.ExercisePrimitives._\nimport se.kth.edx.id2203.core.Ports._\nimport se.kth.edx.id2203.validation._\nimport se.sics.kompics.network._\nimport se.sics.kompics.sl.{Init, _}\nimport se.sics.kompics.{ComponentDefinition => _, Port => _, KompicsEvent}\n\nimport scala.collection.immutable.Set\nimport scala.collection.mutable.ListBuffer","user":"anonymous","dateUpdated":"2018-01-03T14:51:50+0000","config":{"tableHide":false,"editorSetting":{"language":"scala","editOnDblClick":false},"editorMode":"ace/mode/scala","colWidth":12,"editorHide":false,"fontSize":9,"results":{},"enabled":true,"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"import se.kth.edx.id2203.core.ExercisePrimitives._
import se.kth.edx.id2203.core.Ports._
import se.kth.edx.id2203.validation._
import se.sics.kompics.network._
import se.sics.kompics.sl.{Init, _}
import se.sics.kompics.{ComponentDefinition=>_, Port=>_, KompicsEvent}
import scala.collection.immutable.Set
import scala.collection.mutable.ListBuffer
"}]},"apps":[],"jobName":"paragraph_1514130403314_405058411","id":"20160728-150612_1687562708","dateCreated":"2017-12-24T15:46:43+0000","dateStarted":"2018-01-03T14:51:50+0000","dateFinished":"2018-01-03T14:51:59+0000","status":"FINISHED","progressUpdateIntervalMs":500,"$$hashKey":"object:6717"},{"text":"%md\n\n### Part I: Best-Effort Broadcast ###\n\nA Best-Effort Broadcast Abstraction (BEB), in Kompics terms, is a component that **provides** the following port *(already imported in the notebook)*.\n\n class BestEffortBroadcast extends Port {\n indication[BEB_Deliver];\n request[BEB_Broadcast];\n }\n\nA **BEB** component should request `BEB_Broadcast` and indicate `BEB_Deliver` events as defined below:\n\n case class BEB_Deliver(source: Address, payload: KompicsEvent) extends KompicsEvent;\n case class BEB_Broadcast(payload: KompicsEvent) extends KompicsEvent;\n\n\nAs you have already learnt from the course lectures, Best-Effort Broadcast should satisfy the following properties:\n\n1. **Validity**: *If a correct process broadcasts a message m, then every correct process eventually delivers m.*\n2. **No duplication**: *No message is delivered more than once.*\n3. **No creation**: *If a process delivers a message m with sender s, then m was previously broadcast by process s.*\n\nHINT: The recommended algorithm to use in this assignment is *Basic Broadcast* and is described in the following [document](https://d37djvu3ytnwxt.cloudfront.net/assets/courseware/v1/a91e7d1ac75367325c1efd101a9e2138/asset-v1:KTHx+ID2203.1x+2016T3+type@asset+block/basicbroadcast.pdf) in the respective lecture.\n","dateUpdated":"2017-12-24T15:46:43+0000","config":{"editorSetting":{},"editorMode":"ace/mode/markdown","colWidth":12,"editorHide":true,"fontSize":9,"results":[{"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}}],"enabled":true},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"
\n

Part I: Best-Effort Broadcast

\n

A Best-Effort Broadcast Abstraction (BEB), in Kompics terms, is a component that provides the following port (already imported in the notebook).

\n
class BestEffortBroadcast extends Port {\n indication[BEB_Deliver];\n request[BEB_Broadcast];\n}\n
\n

A BEB component should request BEB_Broadcast and indicate BEB_Deliver events as defined below:

\n
 case class BEB_Deliver(source: Address, payload: KompicsEvent) extends KompicsEvent;\n case class BEB_Broadcast(payload: KompicsEvent) extends KompicsEvent;\n
\n

As you have already learnt from the course lectures, Best-Effort Broadcast should satisfy the following properties:

\n
    \n
  1. Validity: If a correct process broadcasts a message m, then every correct process eventually delivers m.
  2. \n
  3. No duplication: No message is delivered more than once.
  4. \n
  5. No creation: If a process delivers a message m with sender s, then m was previously broadcast by process s.
  6. \n
\n

HINT: The recommended algorithm to use in this assignment is Basic Broadcast and is described in the following document in the respective lecture.

\n
"}]},"apps":[],"jobName":"paragraph_1514130403315_404673662","id":"20160915-145354_1020037731","dateCreated":"2017-12-24T15:46:43+0000","status":"READY","errorMessage":"","progressUpdateIntervalMs":500,"$$hashKey":"object:6718"},{"text":"\nclass BasicBroadcast(init: Init[BasicBroadcast]) extends ComponentDefinition {\n\n //BasicBroadcast Subscriptions\n val pLink = requires[PerfectLink];\n val beb = provides[BestEffortBroadcast];\n\n //BasicBroadcast Component State and Initialization\n val (self, topology) = init match {\n case Init(s: Address, t: Set[Address]@unchecked) => (s, t)\n };\n\n //BasicBroadcast Event Handlers\n beb uponEvent {\n case x: BEB_Broadcast => handle {\n for (q <- topology) {\n trigger(PL_Send(q, x) -> pLink);\n }\n }\n }\n\n pLink uponEvent {\n case PL_Deliver(src, BEB_Broadcast(payload)) => handle {\n \n trigger(BEB_Deliver(src,payload) -> beb);\n \n }\n }\n}","user":"anonymous","dateUpdated":"2018-01-03T14:52:19+0000","config":{"lineNumbers":true,"tableHide":false,"editorSetting":{"language":"scala","editOnDblClick":false},"editorMode":"ace/mode/scala","colWidth":12,"editorHide":false,"fontSize":9,"results":{},"enabled":true,"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"defined class BasicBroadcast
"}]},"apps":[],"jobName":"paragraph_1514130403318_403519415","id":"20160728-150736_1548510044","dateCreated":"2017-12-24T15:46:43+0000","dateStarted":"2018-01-03T14:52:19+0000","dateFinished":"2018-01-03T14:52:26+0000","status":"FINISHED","progressUpdateIntervalMs":500,"$$hashKey":"object:6719"},{"text":"checkBEB[BasicBroadcast]();","user":"anonymous","dateUpdated":"2018-01-03T14:52:33+0000","config":{"tableHide":false,"editorSetting":{"language":"scala","editOnDblClick":false},"editorMode":"ace/mode/scala","colWidth":12,"editorHide":false,"fontSize":9,"results":{},"enabled":true,"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"
Your submission has been locally simulated and validated.

Click Here to view the output of the simulation.



Correction Results
PASSED Validity ✔: Eventually every correct process delivers every message broadcasted by correct processes
PASSED No Duplication-No Creation ✔: Every message delivered has been previously broadcasted
✔: No duplicate delivered messages found

Final Comments
**************
Congratulations! Your implementation of the 'Best Effort Broadcast' satisfies all properties!
A unique token has been generated for your submission right below. Please do not edit.

{\"gradingToken\":[45,45,45,45,45,66,69,71,73,78,32,80,71,80,32,77,69,83,83,65,71,69,45,45,45,45,45,10,86,101,114,115,105,111,110,58,32,66,67,80,71,32,118,49,46,53,53,10,10,104,81,73,77,65,57,79,116,77,118,84,69,98,74,49,102,65,81,47,43,77,72,106,68,78,72,89,88,67,90,99,111,49,68,71,84,105,109,98,111,119,98,50,122,70,55,112,104,108,86,108,110,104,51,117,121,120,116,70,119,75,116,107,48,10,90,103,114,76,116,73,102,72,74,122,68,86,72,113,71,84,101,54,55,51,85,119,80,84,102,66,114,102,49,85,51,57,77,99,97,56,43,79,77,48,77,70,55,90,99,100,90,75,79,69,48,66,106,101,109,102,73,88,86,52,110,84,116,120,10,56,114,84,105,67,105,110,111,65,74,116,68,76,71,101,89,90,73,109,115,71,117,98,53,71,98,83,102,90,109,121,68,54,106,57,116,88,57,87,52,109,103,81,55,122,80,104,110,101,73,118,109,119,48,54,68,102,69,98,99,72,75,104,82,10,89,73,103,52,109,120,82,88,87,74,103,75,102,112,106,86,120,97,106,113,107,89,51,77,48,106,122,53,43,48,98,75,71,73,108,52,88,51,118,74,114,122,80,109,83,116,103,102,50,105,67,85,70,114,54,115,103,66,43,99,77,50,106,116,10,102,51,113,53,103,78,49,54,77,100,112,53,48,80,43,116,114,68,101,74,108,65,50,113,52,66,48,48,73,114,72,122,80,55,84,87,120,56,87,69,114,73,87,67,109,102,53,114,80,115,113,53,85,106,57,50,78,117,55,74,47,84,116,110,10,54,109,78,71,111,76,52,49,86,88,65,117,115,117,66,70,122,111,66,47,122,80,47,78,72,78,55,116,43,68,72,47,83,70,50,120,52,115,108,112,55,72,56,115,48,54,50,70,115,107,54,112,76,80,74,68,47,99,70,114,89,84,47,71,10,68,107,120,82,47,90,113,110,47,70,54,122,117,77,55,82,101,102,74,71,79,98,117,122,100,118,89,90,116,113,88,120,83,77,115,113,83,67,48,70,70,50,87,98,66,55,56,43,82,67,75,54,65,113,47,53,97,69,108,100,50,121,68,69,10,55,89,55,120,87,50,43,48,112,75,82,53,84,115,85,73,68,43,122,56,114,52,111,75,83,88,70,53,55,107,90,90,106,87,47,115,69,117,99,55,114,70,80,54,67,113,121,99,56,72,76,108,55,54,43,47,87,99,82,107,103,112,88,83,10,103,111,86,100,70,51,84,43,114,69,77,88,101,110,114,86,119,107,106,51,88,117,110,113,66,107,86,65,109,111,115,47,85,84,72,97,55,98,112,78,89,48,97,112,98,121,82,99,83,86,116,43,106,49,120,88,81,81,66,120,80,98,105,122,10,52,66,102,103,102,88,86,73,110,53,100,51,68,50,106,67,99,103,57,118,107,43,110,43,82,84,54,48,67,97,65,76,55,99,112,80,69,70,57,55,69,89,54,83,81,82,82,110,54,100,52,97,50,74,111,89,83,80,49,120,99,47,71,80,10,116,50,115,80,104,49,82,106,119,72,54,71,108,51,55,79,119,67,115,80,78,56,111,84,100,73,106,118,98,113,119,69,49,51,112,69,122,122,86,86,103,49,83,50,67,121,53,98,107,65,111,54,85,56,52,118,85,73,90,82,109,55,88,83,10,119,65,48,66,119,117,74,88,76,122,119,111,80,87,100,50,68,111,79,76,78,77,52,52,53,98,113,51,79,106,98,118,52,82,120,86,80,105,98,53,119,75,81,119,106,73,75,85,75,69,71,117,90,121,108,89,101,67,80,105,67,79,78,105,10,53,53,101,80,55,56,78,120,50,121,51,81,50,86,52,86,47,47,51,97,83,121,83,109,54,98,71,98,52,79,117,69,116,108,56,75,113,112,119,111,116,79,47,50,84,107,51,80,68,98,72,101,80,47,75,97,72,117,112,51,99,81,82,83,10,57,82,49,89,97,86,83,56,88,52,99,102,90,83,100,98,49,87,103,116,90,118,67,106,111,118,107,51,57,73,103,43,48,83,86,110,53,65,49,65,74,116,105,83,55,109,53,54,89,121,113,49,111,50,88,119,50,114,48,99,79,53,43,97,10,54,112,106,83,110,120,54,102,121,68,89,108,56,119,85,67,72,54,89,52,117,48,76,113,108,113,99,110,110,110,76,70,56,67,121,48,110,77,81,54,89,100,101,66,88,66,112,117,69,52,118,120,102,51,48,111,57,56,79,102,106,89,53,70,10,108,56,116,120,100,53,112,107,56,57,117,56,50,74,50,53,70,75,72,72,10,61,53,109,98,97,10,45,45,45,45,45,69,78,68,32,80,71,80,32,77,69,83,83,65,71,69,45,45,45,45,45,10]}
res0: Boolean = true
"}]},"apps":[],"jobName":"paragraph_1514130403319_403134666","id":"20160830-154208_1529541172","dateCreated":"2017-12-24T15:46:43+0000","dateStarted":"2018-01-03T14:52:33+0000","dateFinished":"2018-01-03T14:52:43+0000","status":"FINISHED","progressUpdateIntervalMs":500,"$$hashKey":"object:6720"},{"text":"%md\n\n### Part II: Reliable Broadcast ###\n\nA Reliable Broadcast Abstraction (RB), in Kompics terms, is a component that **provides** the following port *(already imported in the notebook)*.\n\n class ReliableBroadcast extends Port {\n indication[RB_Deliver];\n request[RB_Broadcast];\n }\n \nAn **RB** component should request `RB_Broadcast` and indicate `RB_Deliver` events, as defined below:\n\n case class RB_Deliver(source: Address, payload: KompicsEvent) extends KompicsEvent;\n case class RB_Broadcast(payload: KompicsEvent) extends KompicsEvent;\n \n\nAs you have already learnt from the course lectures, Reliable Broadcast adds the `Agreement` property into the already existing properties of Best-Effort Broadcast:\n\n1. Validity: *If a correct process broadcasts a message m, then every correct process eventually delivers m.*\n2. No duplication: *No message is delivered more than once.*\n3. No creation: *If a process delivers a message m with sender s, then m was previously broadcast by process s.*\n4. **Agreement**: *If a message m is delivered by some correct process, then m is eventually delivered by every correct process.*\n\nHINT: The recommended algorithm to use in this assignment is *Eager Reliable Broadcast* and is described in page 2 within the following [document](https://d37djvu3ytnwxt.cloudfront.net/assets/courseware/v1/6c144fd806b3568f6e2c5d7d03e27a29/asset-v1:KTHx+ID2203.1x+2016T3+type@asset+block/reliablebroadcast.pdf) in the respective lecture.\n\n**Mind that, to complete this part, you will first have to implement and test Best-Effort Broadcast, defined above.**","dateUpdated":"2017-12-24T15:46:43+0000","config":{"editorSetting":{},"editorMode":"ace/mode/scala","colWidth":12,"editorHide":true,"fontSize":9,"results":[{"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}}],"enabled":true},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"
\n

Part II: Reliable Broadcast

\n

A Reliable Broadcast Abstraction (RB), in Kompics terms, is a component that provides the following port (already imported in the notebook).

\n
class ReliableBroadcast extends Port {\n  indication[RB_Deliver];\n  request[RB_Broadcast];\n}\n
\n

An RB component should request RB_Broadcast and indicate RB_Deliver events, as defined below:

\n
case class RB_Deliver(source: Address, payload: KompicsEvent) extends KompicsEvent;\ncase class RB_Broadcast(payload: KompicsEvent) extends KompicsEvent;\n
\n

As you have already learnt from the course lectures, Reliable Broadcast adds the Agreement property into the already existing properties of Best-Effort Broadcast:

\n
    \n
  1. Validity: If a correct process broadcasts a message m, then every correct process eventually delivers m.
  2. \n
  3. No duplication: No message is delivered more than once.
  4. \n
  5. No creation: If a process delivers a message m with sender s, then m was previously broadcast by process s.
  6. \n
  7. Agreement: If a message m is delivered by some correct process, then m is eventually delivered by every correct process.
  8. \n
\n

HINT: The recommended algorithm to use in this assignment is Eager Reliable Broadcast and is described in page 2 within the following document in the respective lecture.

\n

Mind that, to complete this part, you will first have to implement and test Best-Effort Broadcast, defined above.

\n
"}]},"apps":[],"jobName":"paragraph_1514130403319_403134666","id":"20160915-152029_348185262","dateCreated":"2017-12-24T15:46:43+0000","status":"READY","errorMessage":"","progressUpdateIntervalMs":500,"$$hashKey":"object:6721"},{"text":"\n//Reliable Broadcast\n\nclass EagerReliableBroadcast(init: Init[EagerReliableBroadcast]) extends ComponentDefinition {\n //EagerReliableBroadcast Subscriptions\n val beb = requires[BestEffortBroadcast];\n val rb = provides[ReliableBroadcast];\n\n //EagerReliableBroadcast Component State and Initialization\n val self = init match {\n case Init(s: Address) => s\n };\n val delivered = collection.mutable.Set[KompicsEvent]();\n\n //EagerReliableBroadcast Event Handlers\n rb uponEvent {\n case x@RB_Broadcast(payload) => handle {\n\n trigger(BEB_Broadcast(RB_Broadcast(payload)) -> beb);\n }\n }\n\n beb uponEvent {\n case BEB_Deliver(src, y@RB_Broadcast(payload)) => handle {\n \n if (!delivered.contains(y.payload)){\n \n delivered += y.payload;\n trigger(RB_Deliver(src, y.payload) -> rb);\n trigger(BEB_Broadcast(RB_Broadcast(payload)) -> beb);\n }\n }\n }\n}","user":"anonymous","dateUpdated":"2018-01-03T14:52:48+0000","config":{"lineNumbers":true,"tableHide":false,"editorSetting":{"language":"scala","editOnDblClick":false},"editorMode":"ace/mode/scala","colWidth":12,"editorHide":false,"fontSize":9,"results":{},"enabled":true,"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"defined class EagerReliableBroadcast
"}]},"apps":[],"jobName":"paragraph_1514130403319_403134666","id":"20160728-150932_1018155040","dateCreated":"2017-12-24T15:46:43+0000","dateStarted":"2018-01-03T14:52:48+0000","dateFinished":"2018-01-03T14:52:50+0000","status":"FINISHED","progressUpdateIntervalMs":500,"$$hashKey":"object:6722"},{"text":"checkRB[BasicBroadcast,EagerReliableBroadcast]();","user":"anonymous","dateUpdated":"2018-01-03T14:52:54+0000","config":{"tableHide":false,"editorSetting":{"language":"scala","editOnDblClick":false},"editorMode":"ace/mode/scala","colWidth":12,"editorHide":false,"fontSize":9,"results":{},"enabled":true,"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"
Your submission has been locally simulated and validated.

Click Here to view the output of the simulation.




Correction Results
PASSED Validity ✔: Eventually every correct process delivers every message broadcasted by correct processes
PASSED No Duplication-No Creation ✔: Every message delivered has been previously broadcasted
✔: No duplicate delivered messages found
PASSED Agreement ✔: Every message delivered by a correct process is eventually delivered by every other correct process

Final Comments
**************
Congratulations! Your implementation of the 'Reliable Broadcast' satisfies all properties!
A unique token has been generated for your submission right below. Please do not edit.

{\"gradingToken\":[45,45,45,45,45,66,69,71,73,78,32,80,71,80,32,77,69,83,83,65,71,69,45,45,45,45,45,10,86,101,114,115,105,111,110,58,32,66,67,80,71,32,118,49,46,53,53,10,10,104,81,73,77,65,57,79,116,77,118,84,69,98,74,49,102,65,81,47,55,66,88,66,89,74,108,49,82,74,111,65,89,47,50,86,79,105,75,68,110,104,111,68,103,50,85,86,50,110,81,81,54,115,98,111,54,87,101,54,90,87,84,56,119,10,117,89,52,83,78,74,77,86,75,75,86,80,75,105,90,115,88,86,56,117,103,119,115,50,89,121,71,72,88,68,89,80,108,52,53,78,56,101,119,115,53,97,108,56,122,87,114,66,87,90,69,52,109,50,89,98,55,109,54,87,101,100,101,56,10,116,78,119,88,70,82,74,57,84,97,56,122,51,98,118,47,105,103,122,68,118,104,52,73,97,90,102,101,82,79,86,78,113,56,81,77,48,84,86,116,88,66,114,48,87,90,106,86,111,112,69,71,82,122,116,112,73,75,76,111,49,53,112,68,10,83,79,47,47,54,65,66,69,116,88,56,108,111,70,99,43,49,72,53,52,121,65,114,47,43,67,67,52,66,122,74,82,82,76,90,90,105,69,52,116,117,72,84,89,99,108,106,68,102,107,110,112,111,116,65,68,117,75,103,108,87,72,80,56,10,114,108,71,48,104,78,51,52,75,73,110,80,80,79,118,99,110,110,110,104,68,109,122,66,43,84,122,121,47,72,111,97,107,74,78,102,109,70,118,51,74,66,70,89,110,98,75,57,99,114,80,87,110,87,70,98,97,101,113,75,48,83,102,53,10,81,109,43,119,49,122,67,104,98,82,84,117,71,108,106,102,66,119,99,109,88,69,87,71,55,111,97,102,57,56,73,52,49,98,97,66,113,68,87,84,89,102,73,115,71,68,43,66,54,118,51,70,115,76,47,99,78,116,121,48,112,103,73,53,10,65,69,118,54,98,101,112,77,109,70,79,84,101,118,108,81,75,50,53,107,118,114,117,86,81,70,106,54,115,102,98,70,83,50,73,75,47,69,75,111,80,117,48,70,54,68,119,76,74,56,100,83,89,105,70,114,86,122,99,48,111,107,83,81,10,76,75,67,99,72,81,112,99,117,55,67,78,97,103,72,47,76,65,115,77,51,47,53,73,83,110,77,56,76,68,74,87,72,53,52,56,120,110,120,104,105,101,71,52,50,50,70,54,108,76,65,68,107,47,49,101,82,71,79,83,90,68,80,43,10,48,103,121,81,87,80,77,74,67,81,78,67,79,68,70,117,86,65,106,56,52,57,55,88,72,76,81,78,43,122,98,79,47,102,73,55,107,103,67,87,54,67,112,82,65,43,105,116,88,53,84,74,87,77,90,75,73,57,122,83,75,71,90,55,10,77,80,119,67,82,111,115,114,74,43,108,122,119,97,71,119,48,106,66,54,85,108,74,97,106,81,100,57,97,85,65,90,116,89,65,115,57,51,122,50,100,43,89,87,66,79,80,82,109,49,55,107,88,90,97,76,102,83,87,104,119,68,66,49,10,117,122,120,102,83,73,75,111,110,51,120,122,113,109,119,49,113,115,54,51,114,55,100,67,71,82,111,115,98,52,52,72,70,68,43,47,51,82,57,105,83,72,109,102,67,70,77,119,102,117,102,102,99,117,43,80,88,48,77,71,85,119,106,83,10,119,67,111,66,48,55,52,57,53,118,88,114,56,111,114,78,85,122,66,79,75,119,108,49,117,83,117,54,47,98,47,121,118,74,117,79,81,86,55,90,76,109,104,119,118,109,120,72,108,113,103,121,88,111,79,47,97,49,109,112,56,107,83,67,10,90,97,77,79,56,100,74,98,86,112,89,71,78,116,106,113,56,98,82,73,83,72,65,73,66,51,82,49,119,106,78,86,97,85,102,76,116,76,102,120,103,100,67,76,88,100,47,88,89,108,105,66,119,68,54,114,68,65,70,104,81,50,98,112,10,87,99,76,49,75,57,115,87,86,53,116,86,90,77,80,69,66,89,111,107,47,47,54,80,88,103,48,56,119,102,48,104,88,72,83,73,82,83,118,86,57,52,102,115,69,79,88,78,117,119,78,55,80,48,78,119,70,106,87,99,87,104,88,87,10,75,50,102,66,115,88,83,87,50,109,52,77,78,43,90,101,122,85,81,118,107,117,75,109,83,97,66,47,100,113,114,88,53,109,113,122,85,77,100,87,109,114,111,82,115,57,120,54,120,82,108,104,99,118,107,120,48,120,49,57,120,50,54,73,10,111,65,75,70,57,65,90,65,56,68,106,53,89,87,121,57,68,47,71,104,80,118,120,69,99,80,97,72,55,66,51,117,109,51,112,105,84,51,104,116,68,74,74,77,73,88,86,88,55,52,56,72,82,111,119,105,66,52,103,61,10,61,121,110,103,56,10,45,45,45,45,45,69,78,68,32,80,71,80,32,77,69,83,83,65,71,69,45,45,45,45,45,10]}
res1: Boolean = true
"}]},"apps":[],"jobName":"paragraph_1514130403321_400826173","id":"20160830-154553_1603284544","dateCreated":"2017-12-24T15:46:43+0000","dateStarted":"2018-01-03T14:52:54+0000","dateFinished":"2018-01-03T14:52:59+0000","status":"FINISHED","progressUpdateIntervalMs":500,"$$hashKey":"object:6723"},{"text":"%md\n\n### Part III: Causal-Order Reliable Broadcast ###\n\nA Causal-Order Reliable Broadcast Abstraction (CRB), in Kompics terms, is a component that **provides** the following port *(already imported in the notebook)*.\n\n class CausalOrderReliableBroadcast extends Port {\n indication[CRB_Deliver];\n request[CRB_Broadcast];\n }\n \nA **CRB** component should request `CRB_Broadcast` and indicate `CRB_Deliver` events, as defined below:\n\n case class CRB_Deliver(src: Address, payload: KompicsEvent) extends KompicsEvent;\n case class CRB_Broadcast(payload: KompicsEvent) extends KompicsEvent;\n\n\nAs you have already learnt from the course lectures, Causal-Order Reliable Broadcast adds the `Causal Delivery` property into the already existing properties of Reliable and Best-Effort Broadcast:\n\n1. Validity: *If a correct process broadcasts a message m, then every correct process eventually delivers m.*\n2. No duplication: *No message is delivered more than once.*\n3. No creation: *If a process delivers a message m with sender s, then m was previously broadcast by process s.*\n4. Agreement: *If a message m is delivered by some correct process, then m is eventually delivered by every correct process.*\n5. **Causal delivery**: *For any message m1 that potentially caused a message m2, i.e., m1 → m2, no process delivers m2 unless it has already delivered m1.*\n\nHINT: The recommended algorithm to use in this assignment is *Waiting Causal Broadcast* and is described in page 4 within the following [document](https://d37djvu3ytnwxt.cloudfront.net/assets/courseware/v1/f11d45d4cb0d9685c723dd00de427b8d/asset-v1:KTHx+ID2203.1x+2016T3+type@asset+block/causalbroadcast.pdf) in the respective lecture.\n\n**Also mind, that to complete this part, you will first have to implement and test Best-Effort Broadcast and Reliable Broadcast, defined above.**\n\n\n#### Working with Vector Clocks ####\nWe have already provided you a `VectorClock` data structure **(already imported)** to aid you with the algorithm implementation. You can briefly see the supported operations below:\n\n```scala\n case class VectorClock(var vc: Map[Address, Int]) {\n def inc(addr: Address) : Unit //increases the clock corresponding to the address @addr provided\n def set(addr: Address, value: Int) : Unit //sets the clock of @addr to @value\n def <=(that: VectorClock): Boolean //returns true if this vector clock instance is lower or equal to @that\n }\n object VectorClock {\n def empty(topology: scala.Seq[Address]): VectorClock //generates a vector clock that has an initial clock value of 0 for each address in the @topology provided\n def apply(that: VectorClock): VectorClock //copy constructor of a vector clock. E.g. if vc1 is a vector clock vc2 = VectorClock(vc1) is a copy of vc1\n }\n```\nIn case you want to check the full implementation of the VectorClock, you can find it in our full published gist [here](https://gist.github.com/senorcarbone/5c960ee27a67ec8b6bd42c33303fdcd2).\n","user":"anonymous","dateUpdated":"2018-01-03T14:02:17+0000","config":{"tableHide":false,"editorSetting":{"language":"markdown","editOnDblClick":true},"editorMode":"ace/mode/markdown","colWidth":12,"editorHide":true,"fontSize":9,"results":[{"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}}],"enabled":true},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"
\n

Part III: Causal-Order Reliable Broadcast

\n

A Causal-Order Reliable Broadcast Abstraction (CRB), in Kompics terms, is a component that provides the following port (already imported in the notebook).

\n
class CausalOrderReliableBroadcast extends Port {\n  indication[CRB_Deliver];\n  request[CRB_Broadcast];\n}\n
\n

A CRB component should request CRB_Broadcast and indicate CRB_Deliver events, as defined below:

\n
case class CRB_Deliver(src: Address, payload: KompicsEvent) extends KompicsEvent;\ncase class CRB_Broadcast(payload: KompicsEvent) extends KompicsEvent;\n
\n

As you have already learnt from the course lectures, Causal-Order Reliable Broadcast adds the Causal Delivery property into the already existing properties of Reliable and Best-Effort Broadcast:

\n
    \n
  1. Validity: If a correct process broadcasts a message m, then every correct process eventually delivers m.
  2. \n
  3. No duplication: No message is delivered more than once.
  4. \n
  5. No creation: If a process delivers a message m with sender s, then m was previously broadcast by process s.
  6. \n
  7. Agreement: If a message m is delivered by some correct process, then m is eventually delivered by every correct process.
  8. \n
  9. Causal delivery: For any message m1 that potentially caused a message m2, i.e., m1 → m2, no process delivers m2 unless it has already delivered m1.
  10. \n
\n

HINT: The recommended algorithm to use in this assignment is Waiting Causal Broadcast and is described in page 4 within the following document in the respective lecture.

\n

Also mind, that to complete this part, you will first have to implement and test Best-Effort Broadcast and Reliable Broadcast, defined above.

\n

Working with Vector Clocks

\n

We have already provided you a VectorClock data structure (already imported) to aid you with the algorithm implementation. You can briefly see the supported operations below:

\n
    case class VectorClock(var vc: Map[Address, Int]) {\n        def inc(addr: Address) : Unit  //increases the clock corresponding to the address @addr provided\n        def set(addr: Address, value: Int) : Unit //sets the clock of @addr to @value\n        def <=(that: VectorClock): Boolean   //returns true if this vector clock instance is lower or equal to @that\n    }\n    object VectorClock {\n        def empty(topology: scala.Seq[Address]): VectorClock //generates a vector clock that has an initial clock value of 0 for each address in the @topology provided\n        def apply(that: VectorClock): VectorClock //copy constructor of a vector clock. E.g. if vc1 is a vector clock vc2 = VectorClock(vc1) is a copy of vc1\n    }\n
\n

In case you want to check the full implementation of the VectorClock, you can find it in our full published gist here.

\n
"}]},"apps":[],"jobName":"paragraph_1514130403321_400826173","id":"20160915-154115_478906095","dateCreated":"2017-12-24T15:46:43+0000","dateStarted":"2018-01-03T14:02:17+0000","dateFinished":"2018-01-03T14:02:17+0000","status":"FINISHED","progressUpdateIntervalMs":500,"$$hashKey":"object:6724"},{"text":"\n//Causal Reliable Broadcast\n\ncase class DataMessage(timestamp: VectorClock, payload: KompicsEvent) extends KompicsEvent;\n\nclass WaitingCRB(init: Init[WaitingCRB]) extends ComponentDefinition {\n\n //WaitingCRB Subscriptions\n val rb = requires[ReliableBroadcast];\n val crb = provides[CausalOrderReliableBroadcast];\n\n //WaitingCRB Component State and Initialization\n val (self, vec) = init match {\n case Init(s: Address, t: Set[Address]@unchecked) => (s, VectorClock.empty(t.toSeq))\n };\n\n // val V = VectorClock.empty(init match { case Init(_, t: Set[Address]) => t.toSeq })\n var pending: ListBuffer[(Address, DataMessage)] = ListBuffer();\n var lsn = 0;\n\n\n //WaitingCRB Event Handlers\n crb uponEvent {\n case x: CRB_Broadcast => handle {\n var W = VectorClock(vec);\n W.set(self, lsn);\n lsn = lsn + 1;\n trigger(RB_Broadcast((DataMessage(W, x.payload))) -> rb);\n /* trigger(RB_Broadcast(CRB_Broadcast(DataMessage(W, x.payload))) -> rb); */\n }\n }\n\n rb uponEvent {\n case x@RB_Deliver(src: Address, msg: DataMessage) => handle {\n \n pending += ((src, msg));\n while(pending.exists { p => p._2.timestamp<=vec }){\n for (p <- pending) {\n if (p._2.timestamp<=vec) {\n val (s,m) = p; \n pending -= p;\n vec.inc(s);\n trigger(CRB_Deliver(s,m.payload) -> crb);\n }\n }\n }\n }\n }\n}\n","user":"anonymous","dateUpdated":"2018-01-03T15:35:08+0000","config":{"lineNumbers":true,"tableHide":false,"editorSetting":{"language":"scala","editOnDblClick":false},"editorMode":"ace/mode/scala","colWidth":12,"editorHide":false,"fontSize":9,"results":{},"enabled":true,"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"defined class DataMessage
defined class WaitingCRB
"}]},"apps":[],"jobName":"paragraph_1514130403321_400826173","id":"20160728-150719_1155234225","dateCreated":"2017-12-24T15:46:43+0000","dateStarted":"2018-01-03T15:34:13+0000","dateFinished":"2018-01-03T15:34:14+0000","status":"FINISHED","progressUpdateIntervalMs":500,"$$hashKey":"object:6725"},{"text":"checkCRB[BasicBroadcast, EagerReliableBroadcast, WaitingCRB]();","user":"anonymous","dateUpdated":"2018-01-03T15:34:18+0000","config":{"tableHide":false,"editorSetting":{"language":"scala","editOnDblClick":false},"editorMode":"ace/mode/scala","colWidth":12,"editorHide":false,"fontSize":9,"results":{},"enabled":true,"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"
Your submission has been locally simulated and validated.

Click Here to view the output of the simulation.





Correction Results
PASSED Validity ✔: Eventually every correct process delivers every message broadcasted by correct processes
PASSED No Duplication-No Creation ✔: Every message delivered has been previously broadcasted
✔: No duplicate delivered messages found
PASSED Agreement ✔: Every message delivered by a correct process is eventually delivered by every other correct process
PASSED Causal Delivery ✔: All messages delivered respect causality order

Final Comments
**************
Congratulations! Your implementation of the 'Causal Order Reliable Broadcast' satisfies all properties!
A unique token has been generated for your submission right below. Please do not edit.

{\"gradingToken\":[45,45,45,45,45,66,69,71,73,78,32,80,71,80,32,77,69,83,83,65,71,69,45,45,45,45,45,10,86,101,114,115,105,111,110,58,32,66,67,80,71,32,118,49,46,53,53,10,10,104,81,73,77,65,57,79,116,77,118,84,69,98,74,49,102,65,81,47,47,82,83,108,81,100,66,49,118,83,86,72,50,117,82,67,72,67,122,102,55,43,100,77,98,51,117,98,49,73,77,103,103,75,56,89,120,55,69,98,68,53,43,105,110,10,76,117,51,67,119,51,114,112,75,80,68,55,97,99,56,110,56,89,114,50,116,121,85,110,50,80,47,71,102,76,90,119,118,43,69,90,112,81,110,70,98,54,48,101,105,122,86,69,122,71,48,78,114,69,119,51,88,70,80,65,114,101,79,81,10,69,54,98,85,65,50,81,104,50,90,84,47,109,50,66,100,68,115,67,105,121,85,49,89,109,108,121,97,100,118,43,47,51,75,111,74,47,104,78,80,85,98,113,69,114,82,49,120,68,56,84,74,77,80,47,109,70,108,80,52,50,103,114,72,10,105,118,104,105,82,119,107,65,107,120,89,57,112,51,109,108,72,100,79,101,119,101,77,51,86,65,47,74,81,65,74,98,100,117,49,48,82,70,57,54,66,113,68,51,69,116,70,76,83,67,49,79,113,82,111,86,106,71,80,68,87,72,78,66,10,72,72,80,106,114,43,88,101,68,116,90,80,99,103,51,115,89,71,87,54,99,114,66,57,78,74,83,43,116,79,51,107,75,48,118,107,80,108,84,122,122,121,53,80,101,68,68,90,79,65,79,106,114,109,76,116,55,52,47,73,65,115,84,102,10,109,65,81,106,80,99,69,70,86,71,82,89,66,118,67,54,90,49,105,114,77,110,113,118,51,85,118,121,72,89,120,50,118,100,72,75,87,72,57,82,70,56,114,70,47,120,119,81,102,67,79,66,108,72,50,111,66,72,52,89,78,55,65,81,10,68,68,80,53,71,102,107,103,113,49,115,111,70,98,104,84,109,89,113,88,117,70,103,47,88,78,87,105,100,69,104,118,109,50,47,100,78,43,99,85,122,114,105,52,89,85,67,111,110,121,109,104,118,107,50,111,56,88,108,117,50,115,101,120,10,89,111,98,47,116,90,115,122,105,55,50,110,113,104,84,115,108,49,75,65,49,105,86,99,57,67,113,53,53,114,110,109,116,83,107,100,116,89,87,84,117,76,48,57,56,76,50,119,69,57,122,72,104,50,48,104,108,50,53,71,83,57,100,73,10,56,54,117,51,74,107,104,53,79,106,122,101,121,56,109,49,108,100,54,90,114,97,114,49,120,51,77,103,87,74,53,51,107,112,106,76,81,89,69,109,49,43,74,67,66,75,56,43,100,110,78,114,110,87,86,112,108,83,69,51,98,43,84,85,10,51,73,109,43,114,47,47,110,79,70,120,107,117,90,78,117,54,107,52,65,51,121,69,43,89,55,99,52,56,90,100,101,111,74,110,100,107,68,114,76,97,73,79,77,49,105,101,114,107,112,109,115,118,121,99,81,120,56,89,83,121,73,115,78,10,68,85,117,101,65,47,68,84,77,114,90,74,100,67,101,53,88,99,112,105,71,71,47,114,52,103,111,68,48,115,81,50,84,71,103,90,106,65,56,67,68,100,107,55,106,106,104,81,85,117,57,54,56,110,121,79,115,70,84,67,80,50,88,83,10,119,70,52,66,77,118,84,117,89,87,117,73,53,55,114,100,104,109,48,66,100,101,51,47,73,105,83,69,111,55,106,57,72,115,79,99,90,82,104,78,75,89,107,120,55,76,51,87,49,114,81,120,65,109,106,75,106,84,99,76,84,87,52,75,10,104,104,79,54,111,74,75,72,52,80,104,51,115,79,87,114,118,69,56,57,80,113,105,87,109,88,57,103,70,112,98,122,110,104,113,81,120,118,77,56,54,66,88,74,115,119,100,81,49,99,77,78,102,84,68,100,76,100,57,116,114,80,105,97,10,76,74,69,107,100,115,49,102,56,84,48,54,82,122,72,109,110,76,86,75,81,48,54,113,86,107,56,106,121,73,119,71,117,114,118,100,54,87,66,90,66,104,80,52,49,80,76,84,118,52,107,74,105,48,57,120,119,78,89,70,54,122,74,85,10,98,112,88,78,65,115,98,89,74,100,76,71,120,54,53,117,72,116,107,68,50,117,71,79,43,67,57,49,104,48,120,71,116,72,114,56,70,82,84,77,110,49,114,83,113,112,73,109,90,53,87,122,68,53,119,76,55,83,102,99,122,75,106,103,10,89,56,117,75,111,69,49,74,114,48,75,76,55,100,115,85,71,86,57,78,74,70,117,117,108,101,109,51,78,88,113,120,72,108,87,76,86,78,53,110,76,112,68,107,105,109,71,82,120,103,84,73,103,104,113,77,54,72,75,87,78,57,97,89,10,109,77,115,105,78,50,77,97,43,71,85,84,53,48,97,73,73,43,107,85,111,114,50,52,50,119,102,49,57,66,84,111,117,111,102,83,108,88,54,57,112,116,43,48,107,50,89,102,47,72,89,74,116,43,71,112,50,56,67,110,102,75,65,86,10,61,107,81,87,49,10,45,45,45,45,45,69,78,68,32,80,71,80,32,77,69,83,83,65,71,69,45,45,45,45,45,10]}
res14: Boolean = true
"}]},"apps":[],"jobName":"paragraph_1514130403321_400826173","id":"20160728-150824_64351046","dateCreated":"2017-12-24T15:46:43+0000","dateStarted":"2018-01-03T15:34:18+0000","dateFinished":"2018-01-03T15:34:22+0000","status":"FINISHED","progressUpdateIntervalMs":500,"$$hashKey":"object:6726"},{"dateUpdated":"2017-12-24T15:46:43+0000","config":{"editorSetting":{"language":"scala","editOnDblClick":false},"colWidth":12,"editorMode":"ace/mode/scala","fontSize":9,"results":{},"enabled":true},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1514130403321_400826173","id":"20171030-153216_12031065","dateCreated":"2017-12-24T15:46:43+0000","status":"READY","errorMessage":"","progressUpdateIntervalMs":500,"$$hashKey":"object:6727"}],"name":"Exercise: Broadcast Abstractions","id":"2D1U3JGQ5","angularObjects":{"2BKQCVH92:shared_process":[],"2CVXXPNWV:shared_process":[]},"config":{"looknfeel":"default","personalizedMode":"false"},"info":{}} -------------------------------------------------------------------------------- /Exercise Broadcast Abstractions/Exercise-_Broadcast_Abstractions.md: -------------------------------------------------------------------------------- 1 | ### Assignment 2: From Best Effort to Causal Order Reliable Broadcast ### 2 | 3 | This is the first programming assignment where you will have to build and reuse multiple components. 4 | Starting bottom-up, you will first have to implement best effort broadcast, then reliable broadcast and finally causal order reliable broadcast. 5 | Mind that passing each component check will give you a partial grade and therefore you will need to pass all checks to get the full grade for this programming assignment. 6 | 7 | Things to Remember: 8 | 1. Some components such as PerfectLink, Network and Timer are already provided. No need to implement them. 9 | 2. Execute the imports defined below before compiling your component implementations. 10 | 3. We recommend making use of the component state and internal messages we have provided, if any, to complete the implementation logic. 11 | 4. You can always print messages to the output log, from within handlers to see what happens during the simulation. e.g. println(s"Process $self delivers message $msg"); 12 | 5. Remember that during the simulation check you can print and observe the simulation time, i.e. with System.currentTimeMillis(). 13 | 5. Do not forget to run the checker code block after each component implementation to ensure that all properties are satisfied before exporting and submitting the notebook. 14 | 6. You can always restart the Kompics Interpreter to start fresh (Interpreter→KompicsInterpreter→Click Restart) 15 | 7. Do not submit just the grading token to edx. You will have to submit the whole exported notebook content to get your grade. 16 | 17 | Good luck! :) 18 | 19 | # Part I: Best-Effort Broadcast 20 | A Best-Effort Broadcast Abstraction (BEB), in Kompics terms, is a component that provides the following port (already imported in the notebook). 21 | ```scala 22 | class BestEffortBroadcast extends Port { 23 | indication[BEB_Deliver]; 24 | request[BEB_Broadcast]; 25 | } 26 | ``` 27 | A __BEB__ component should request BEB_Broadcast and indicate BEB_Deliver events as defined below: 28 | ```scala 29 | case class BEB_Deliver(source: Address, payload: KompicsEvent) extends KompicsEvent; 30 | case class BEB_Broadcast(payload: KompicsEvent) extends KompicsEvent; 31 | ``` 32 | As you have already learnt from the course lectures, Best-Effort Broadcast should satisfy the following properties: 33 | 34 | - __Validity__: If a correct process broadcasts a message m, then every correct process eventually delivers m. 35 | - __No duplication__: No message is delivered more than once. 36 | - __No creation__: If a process delivers a message m with sender s, then m was previously broadcast by process s. 37 | 38 | 39 | # Part II: Reliable Broadcast 40 | A Reliable Broadcast Abstraction (RB), in Kompics terms, is a component that provides the following port (already imported in the notebook). 41 | ```scala 42 | class ReliableBroadcast extends Port { 43 | indication[RB_Deliver]; 44 | request[RB_Broadcast]; 45 | } 46 | ``` 47 | An __RB__ component should request RB_Broadcast and indicate RB_Deliver events, as defined below: 48 | ```scala 49 | case class RB_Deliver(source: Address, payload: KompicsEvent) extends KompicsEvent; 50 | case class RB_Broadcast(payload: KompicsEvent) extends KompicsEvent; 51 | ``` 52 | As you have already learnt from the course lectures, Reliable Broadcast adds the Agreement property into the already existing properties of Best-Effort Broadcast: 53 | 54 | - Validity: If a correct process broadcasts a message m, then every correct process eventually delivers m. 55 | - No duplication: No message is delivered more than once. 56 | - No creation: If a process delivers a message m with sender s, then m was previously broadcast by process s. 57 | - __Agreement__: If a message m is delivered by some correct process, then m is eventually delivered by every correct process. 58 | 59 | Mind that, to complete this part, you will first have to implement and test Best-Effort Broadcast, defined above. 60 | 61 | # Part III: Causal-Order Reliable Broadcast 62 | A Causal-Order Reliable Broadcast Abstraction (CRB), in Kompics terms, is a component that __provides__ the following port (already imported in the notebook). 63 | ```scala 64 | class CausalOrderReliableBroadcast extends Port { 65 | indication[CRB_Deliver]; 66 | request[CRB_Broadcast]; 67 | } 68 | ``` 69 | A __CRB__ component should request CRB_Broadcast and indicate CRB_Deliver events, as defined below: 70 | ```scala 71 | case class CRB_Deliver(src: Address, payload: KompicsEvent) extends KompicsEvent; 72 | case class CRB_Broadcast(payload: KompicsEvent) extends KompicsEvent; 73 | ``` 74 | As you have already learnt from the course lectures, Causal-Order Reliable Broadcast adds the Causal Delivery property into the already existing properties of Reliable and Best-Effort Broadcast: 75 | 76 | - Validity: If a correct process broadcasts a message m, then every correct process eventually delivers m. 77 | - No duplication: No message is delivered more than once. 78 | - No creation: If a process delivers a message m with sender s, then m was previously broadcast by process s. 79 | - Agreement: If a message m is delivered by some correct process, then m is eventually delivered by every correct process. 80 | - __Causal delivery__: For any message m1 that potentially caused a message m2, i.e., m1 → m2, no process delivers m2 unless it has already delivered m1. 81 | 82 | Also mind, that to complete this part, you will first have to implement and test Best-Effort Broadcast and Reliable Broadcast, defined above. 83 | 84 | Working with Vector Clocks 85 | We have already provided you a VectorClock data structure (already imported) to aid you with the algorithm implementation. You can briefly see the supported operations below: 86 | ```scala 87 | case class VectorClock(var vc: Map[Address, Int]) { 88 | def inc(addr: Address) : Unit //increases the clock corresponding to the address @addr provided 89 | def set(addr: Address, value: Int) : Unit //sets the clock of @addr to @value 90 | def <=(that: VectorClock): Boolean //returns true if this vector clock instance is lower or equal to @that 91 | } 92 | object VectorClock { 93 | def empty(topology: scala.Seq[Address]): VectorClock //generates a vector clock that has an initial clock value of 0 for each address in the @topology provided 94 | def apply(that: VectorClock): VectorClock //copy constructor of a vector clock. E.g. if vc1 is a vector clock vc2 = VectorClock(vc1) is a copy of vc1 95 | } 96 | ``` -------------------------------------------------------------------------------- /Exercise Broadcast Abstractions/Exercise-_Broadcast_Abstractions.scala: -------------------------------------------------------------------------------- 1 | import se.kth.edx.id2203.core.ExercisePrimitives._ 2 | import se.kth.edx.id2203.core.Ports._ 3 | import se.kth.edx.id2203.validation._ 4 | import se.sics.kompics.network._ 5 | import se.sics.kompics.sl.{Init, _} 6 | import se.sics.kompics.{ComponentDefinition => _, Port => _, KompicsEvent} 7 | 8 | import scala.collection.immutable.Set 9 | import scala.collection.mutable.ListBuffer 10 | 11 | class BasicBroadcast(init: Init[BasicBroadcast]) extends ComponentDefinition { 12 | 13 | //BasicBroadcast Subscriptions 14 | val pLink = requires[PerfectLink]; 15 | val beb = provides[BestEffortBroadcast]; 16 | 17 | //BasicBroadcast Component State and Initialization 18 | val (self, topology) = init match { 19 | case Init(s: Address, t: Set[Address]@unchecked) => (s, t) 20 | }; 21 | 22 | //BasicBroadcast Event Handlers 23 | beb uponEvent { 24 | case x: BEB_Broadcast => handle { 25 | for (q <- topology) { 26 | trigger(PL_Send(q, x) -> pLink); 27 | } 28 | } 29 | } 30 | 31 | pLink uponEvent { 32 | case PL_Deliver(src, BEB_Broadcast(payload)) => handle { 33 | 34 | trigger(BEB_Deliver(src,payload) -> beb); 35 | 36 | } 37 | } 38 | } 39 | 40 | //Reliable Broadcast 41 | 42 | class EagerReliableBroadcast(init: Init[EagerReliableBroadcast]) extends ComponentDefinition { 43 | //EagerReliableBroadcast Subscriptions 44 | val beb = requires[BestEffortBroadcast]; 45 | val rb = provides[ReliableBroadcast]; 46 | 47 | //EagerReliableBroadcast Component State and Initialization 48 | val self = init match { 49 | case Init(s: Address) => s 50 | }; 51 | val delivered = collection.mutable.Set[KompicsEvent](); 52 | 53 | //EagerReliableBroadcast Event Handlers 54 | rb uponEvent { 55 | case x@RB_Broadcast(payload) => handle { 56 | 57 | trigger(BEB_Broadcast(RB_Broadcast(payload)) -> beb); 58 | } 59 | } 60 | 61 | beb uponEvent { 62 | case BEB_Deliver(src, y@RB_Broadcast(payload)) => handle { 63 | 64 | if (!delivered.contains(y.payload)){ 65 | 66 | delivered += y.payload; 67 | trigger(RB_Deliver(src, y.payload) -> rb); 68 | trigger(BEB_Broadcast(RB_Broadcast(payload)) -> beb); 69 | } 70 | } 71 | } 72 | } 73 | 74 | 75 | //Causal Reliable Broadcast 76 | 77 | case class DataMessage(timestamp: VectorClock, payload: KompicsEvent) extends KompicsEvent; 78 | 79 | class WaitingCRB(init: Init[WaitingCRB]) extends ComponentDefinition { 80 | 81 | //WaitingCRB Subscriptions 82 | val rb = requires[ReliableBroadcast]; 83 | val crb = provides[CausalOrderReliableBroadcast]; 84 | 85 | //WaitingCRB Component State and Initialization 86 | val (self, vec) = init match { 87 | case Init(s: Address, t: Set[Address]@unchecked) => (s, VectorClock.empty(t.toSeq)) 88 | }; 89 | 90 | // val V = VectorClock.empty(init match { case Init(_, t: Set[Address]) => t.toSeq }) 91 | var pending: ListBuffer[(Address, DataMessage)] = ListBuffer(); 92 | var lsn = 0; 93 | 94 | 95 | //WaitingCRB Event Handlers 96 | crb uponEvent { 97 | case x: CRB_Broadcast => handle { 98 | var W = VectorClock(vec); 99 | W.set(self, lsn); 100 | lsn = lsn + 1; 101 | trigger(RB_Broadcast((DataMessage(W, x.payload))) -> rb); 102 | } 103 | } 104 | 105 | rb uponEvent { 106 | case x@RB_Deliver(src: Address, msg: DataMessage) => handle { 107 | pending += ((src, msg)); 108 | while(pending.exists { p => p._2.timestamp<=vec }){ 109 | for (p <- pending) { 110 | if (p._2.timestamp<=vec) { 111 | val (s,m) = p; 112 | pending -= p; 113 | vec.inc(s); 114 | trigger(CRB_Deliver(s,m.payload) -> crb); 115 | } 116 | } 117 | } 118 | } 119 | } 120 | } -------------------------------------------------------------------------------- /Exercise SharedMemory/Exercise-SharedMemory.json: -------------------------------------------------------------------------------- 1 | {"paragraphs":[{"text":"%md\n\n### Implementing an Atomic N-N register \n\nIn this programming assignment you will have to complete the implementation of an atomic register that supports multiple writers and readers.\n\nWhen you are done you simply have to export your notebook and then upload it in the \"Programming Exercise 3\" page.\n\n**Things to Remember**:\n1. Basic components such as `PerfectLink`, `Network` and `Timer` are already provided. No need to implement them.\n2. Execute the imports defined below **before** compiling your component implementations.\n3. We recommend making use of the component state and internal messages we have provided, if any, to complete the implementation logic.\n4. You can always print messages to the output log, from within handlers to see what happens during the simulation. e.g. `println(s\"Process $self delivers message $msg\");`\n5. Remember that during the simulation check you can print and observe the simulation time, i.e. with `System.currentTimeMillis()`.\n5. Do not forget to run the checker code block after each component implementation to ensure that all properties are satisfied **before** exporting and submitting the notebook.\n6. You can always restart the Kompics Interpreter to start fresh (Interpreter→KompicsInterpreter→Click Restart)\n\nGood luck! :)","dateUpdated":"2018-01-05T14:09:00+0000","config":{"editorSetting":{},"editorMode":"ace/mode/scala","colWidth":12,"editorHide":true,"fontSize":9,"results":[{"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}}],"enabled":true},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"
\n

Implementing an Atomic N-N register

\n

In this programming assignment you will have to complete the implementation of an atomic register that supports multiple writers and readers.

\n

When you are done you simply have to export your notebook and then upload it in the “Programming Exercise 3” page.

\n

Things to Remember:
1. Basic components such as PerfectLink, Network and Timer are already provided. No need to implement them.
2. Execute the imports defined below before compiling your component implementations.
3. We recommend making use of the component state and internal messages we have provided, if any, to complete the implementation logic.
4. You can always print messages to the output log, from within handlers to see what happens during the simulation. e.g. println(s"Process $self delivers message $msg");
5. Remember that during the simulation check you can print and observe the simulation time, i.e. with System.currentTimeMillis().
5. Do not forget to run the checker code block after each component implementation to ensure that all properties are satisfied before exporting and submitting the notebook.
6. You can always restart the Kompics Interpreter to start fresh (Interpreter→KompicsInterpreter→Click Restart)

\n

Good luck! :)

\n
"}]},"apps":[],"jobName":"paragraph_1515161340376_-494057230","id":"20160920-133253_275876456","dateCreated":"2018-01-05T14:09:00+0000","status":"READY","errorMessage":"","progressUpdateIntervalMs":500,"focus":true,"$$hashKey":"object:179"},{"text":"//Rremember to execute the following imports first\nimport se.kth.edx.id2203.core.ExercisePrimitives._\nimport se.kth.edx.id2203.core.Ports._\nimport se.kth.edx.id2203.validation._\nimport se.sics.kompics.network._\nimport se.sics.kompics.sl.{Init, _}\nimport se.sics.kompics.{ComponentDefinition => _, Port => _,KompicsEvent}\n\nimport scala.collection.mutable.Map\nimport scala.language.implicitConversions","user":"anonymous","dateUpdated":"2018-01-08T10:35:01+0000","config":{"editorSetting":{"language":"scala","editOnDblClick":false},"editorMode":"ace/mode/scala","colWidth":12,"editorHide":false,"fontSize":9,"results":{},"enabled":true,"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"import se.kth.edx.id2203.core.ExercisePrimitives._
import se.kth.edx.id2203.core.Ports._
import se.kth.edx.id2203.validation._
import se.sics.kompics.network._
import se.sics.kompics.sl.{Init, _}
import se.sics.kompics.{ComponentDefinition=>_, Port=>_, KompicsEvent}
import scala.collection.mutable.Map
import scala.language.implicitConversions
"}]},"apps":[],"jobName":"paragraph_1515161340378_-493287732","id":"20160830-120308_471915891","dateCreated":"2018-01-05T14:09:00+0000","dateStarted":"2018-01-08T10:35:01+0000","dateFinished":"2018-01-08T10:35:01+0000","status":"FINISHED","progressUpdateIntervalMs":500,"$$hashKey":"object:180"},{"text":"%md\n\n### Mini Scala-Refresher : The Scala Option ###\n\nIn this assignment you will have to work with Option types, so let's recap how they work. An `Option[T]` is a container for a value of type `T` which is **optional**. \nThat means that in case the value has been set, then `Option[T]` is actually an instance of `Some[T]`, which in turn contains the actual value of type `T`. \nIn case its value has not been set then the `Option[A]` is the object `None`.\n\nThus, it is good to have in mind the following e.g. for any `value: Option[Any]`:\n\n\n1.When you want to initialize your optional value do it as such: \n```scala \nvalue = Some(myInitialValue) \n//or\nvalue = None;\n```\n2.In case you need to provide a default value in case of a `None` when you want to access an optional type you can do so like this:\n```scala\nval myVal:T = value.getOrElse(myDefaultValue)\n```\nOtherwise you can always simply get its value when you are sure it is not `None` like this:\n```scala\nif(value.isDefined){\n myVal = value.get\n}\n```\n3.Beware of the following assignment: for `val myVal :Option[Any] = Some(1334)` then `val myOtherVal : Option[Any] = Some(myVal)` will not be `Some(1334)` but `Some(Some(1334))`","dateUpdated":"2018-01-05T14:09:00+0000","config":{"editorSetting":{},"editorMode":"ace/mode/scala","colWidth":12,"editorHide":true,"fontSize":9,"results":[{"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}}],"enabled":true},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"
\n

Mini Scala-Refresher : The Scala Option

\n

In this assignment you will have to work with Option types, so let’s recap how they work. An Option[T] is a container for a value of type T which is optional.
That means that in case the value has been set, then Option[T] is actually an instance of Some[T], which in turn contains the actual value of type T.
In case its value has not been set then the Option[A] is the object None.

\n

Thus, it is good to have in mind the following e.g. for any value: Option[Any]:

\n

1.When you want to initialize your optional value do it as such:

\n
value = Some(myInitialValue) \n//or\nvalue = None;\n
\n

2.In case you need to provide a default value in case of a None when you want to access an optional type you can do so like this:

\n
val myVal:T = value.getOrElse(myDefaultValue)\n
\n

Otherwise you can always simply get its value when you are sure it is not None like this:

\n
if(value.isDefined){\n    myVal = value.get\n}\n
\n

3.Beware of the following assignment: for val myVal :Option[Any] = Some(1334) then val myOtherVal : Option[Any] = Some(myVal) will not be Some(1334) but Some(Some(1334))

\n
"}]},"apps":[],"jobName":"paragraph_1515161340378_-493287732","id":"20160920-163834_1484371572","dateCreated":"2018-01-05T14:09:00+0000","status":"READY","errorMessage":"","progressUpdateIntervalMs":500,"$$hashKey":"object:181"},{"text":"%md\n\n## The N-N Atomic Register ##\n\nA (single) Atomic Register Abstraction (AR), in Kompics terms, is a component that **provides** the following port *(already imported in the notebook)*.\n\n class AtomicRegister extends Port {\n request[AR_Read_Request]\n request[AR_Write_Request]\n indication[AR_Read_Response]\n indication[AR_Write_Response]\n }\n\n\nAn **AR** component should request reads (`AR_Read_Request`) or writes (`AR_Write_Request`) and respond with `AR_Read_Response` or `AR_Write_Response` events respectively as defined below:\n\n case class AR_Read_Request() extends KompicsEvent\n case class AR_Read_Response(value: Option[Any]) extends KompicsEvent\n case class AR_Write_Request(value: Any) extends KompicsEvent\n case class AR_Write_Response() extends KompicsEvent\n\n\nAs you have already learnt from the course lectures, Atomic Registers should be linerarizable and also terminate which we summarize with the following properties:\n\n1. **Termination**: *If a correct process invokes an operation, then the operation eventually completes.*\n2. **Atomicity**: *Every read operation returns the value that was written most recently in a hypothetical execution, where every failed operation appears to be complete or does not appear to have been invoked at all, and every complete operation appears to have been executed at some instant between its invocation and its completion.*\n\n\nHINT: The recommended algorithm to use in this assignment is *Read-Impose Write-Consult Majority* and is described at page 3 within the following [document](https://d37djvu3ytnwxt.cloudfront.net/assets/courseware/v1/1c5fbe3090dfe445c8858e42c5925d0f/asset-v1:KTHx+ID2203.1x+2016T3+type@asset+block/atomicregister.pdf) in the respective lecture.\n","user":"anonymous","dateUpdated":"2018-01-05T15:51:51+0000","config":{"editorSetting":{"language":"markdown","editOnDblClick":true},"editorMode":"ace/mode/markdown","colWidth":12,"editorHide":true,"fontSize":9,"results":[{"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}}],"enabled":true,"tableHide":false},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"
\n

The N-N Atomic Register

\n

A (single) Atomic Register Abstraction (AR), in Kompics terms, is a component that provides the following port (already imported in the notebook).

\n
 class AtomicRegister extends Port {\n   request[AR_Read_Request]\n   request[AR_Write_Request]\n   indication[AR_Read_Response]\n   indication[AR_Write_Response]\n }\n
\n

An AR component should request reads (AR_Read_Request) or writes (AR_Write_Request) and respond with AR_Read_Response or AR_Write_Response events respectively as defined below:

\n
 case class AR_Read_Request() extends KompicsEvent\n case class AR_Read_Response(value: Option[Any]) extends KompicsEvent\n case class AR_Write_Request(value: Any) extends KompicsEvent\n case class AR_Write_Response() extends KompicsEvent\n
\n

As you have already learnt from the course lectures, Atomic Registers should be linerarizable and also terminate which we summarize with the following properties:

\n
    \n
  1. Termination: If a correct process invokes an operation, then the operation eventually completes.
  2. \n
  3. Atomicity: Every read operation returns the value that was written most recently in a hypothetical execution, where every failed operation appears to be complete or does not appear to have been invoked at all, and every complete operation appears to have been executed at some instant between its invocation and its completion.
  4. \n
\n

HINT: The recommended algorithm to use in this assignment is Read-Impose Write-Consult Majority and is described at page 3 within the following document in the respective lecture.

\n
"}]},"apps":[],"jobName":"paragraph_1515161340379_-493672481","id":"20160920-163704_1475979424","dateCreated":"2018-01-05T14:09:00+0000","dateStarted":"2018-01-05T15:51:51+0000","dateFinished":"2018-01-05T15:51:51+0000","status":"FINISHED","progressUpdateIntervalMs":500,"$$hashKey":"object:182"},{"text":"\n //The following events are to be used internally by the Atomic Register implementation below\n case class READ(rid: Int) extends KompicsEvent;\n case class VALUE(rid: Int, ts: Int, wr: Int, value: Option[Any]) extends KompicsEvent;\n case class WRITE(rid: Int, ts: Int, wr: Int, writeVal: Option[Any]) extends KompicsEvent;\n case class ACK(rid: Int) extends KompicsEvent;\n\n /**\n * This augments tuples with comparison operators implicitly, which you can use in your code. \n * examples: (1,2) > (1,4) yields 'false' and (5,4) <= (7,4) yields 'true' \n */\n implicit def addComparators[A](x: A)(implicit o: math.Ordering[A]): o.Ops = o.mkOrderingOps(x);\n\n//HINT: After you execute the latter implicit ordering you can compare tuples as such within your component implementation:\n(1,2) <= (1,4);\n","user":"anonymous","dateUpdated":"2018-01-08T10:35:05+0000","config":{"editorSetting":{"language":"scala","editOnDblClick":false},"editorMode":"ace/mode/scala","colWidth":12,"fontSize":9,"results":{},"enabled":true,"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"defined class READ
defined class VALUE
defined class WRITE
defined class ACK
addComparators: [A](x: A)(implicit o: scala.math.Ordering[A])o.Ops
res2: Boolean = true
"}]},"apps":[],"jobName":"paragraph_1515161340379_-493672481","id":"20160920-164336_1137661827","dateCreated":"2018-01-05T14:09:00+0000","dateStarted":"2018-01-08T10:35:05+0000","dateFinished":"2018-01-08T10:35:07+0000","status":"FINISHED","progressUpdateIntervalMs":500,"$$hashKey":"object:183"},{"text":"\nclass ReadImposeWriteConsultMajority(init: Init[ReadImposeWriteConsultMajority]) extends ComponentDefinition {\n\n //subscriptions\n\n val nnar = provides[AtomicRegister];\n\n val pLink = requires[PerfectLink];\n val beb = requires[BestEffortBroadcast];\n\n //state and initialization\n\n val (self: Address, n: Int, selfRank: Int) = init match {\n case Init(selfAddr: Address, n: Int) => (selfAddr, n, AddressUtils.toRank(selfAddr))\n };\n\n var (ts, wr) = (0, 0);\n var value: Option[Any] = None;\n var acks = 0;\n var readval: Option[Any] = None;\n var writeval: Option[Any] = None;\n var rid = 0;\n var readlist: Map[Address, (Int, Int, Option[Any])] = Map.empty\n var reading = false;\n\n //handlers\n\n nnar uponEvent {\n case AR_Read_Request() => handle {\n rid = rid + 1;\n acks = 0;\n readlist = Map.empty;\n reading = true;\n println(s\"($self) READ: BEB_Broadcasting -> rid: $rid reading: $reading\");\n trigger(BEB_Broadcast(READ(rid)) -> beb);\n };\n case AR_Write_Request(wval) => handle { \n rid = rid + 1;\n /*writeval = wval;*/\n writeval = Some(wval);\n acks = 0;\n readlist = Map.empty;\n trigger(BEB_Broadcast(READ(rid)) -> beb);\n println(s\"($self) WRITE: BEB_Broadcasting -> rid: $rid\");\n }\n }\n\n beb uponEvent {\n case BEB_Deliver(src, READ(readID)) => handle {\n trigger(PL_Send(src, VALUE(readID, ts, wr, value)) -> pLink);\n println(s\"($self) Sendind VALUE form $src -> rid: $readID timestamp: $ts wr: $wr value: $value\");\n }\n case BEB_Deliver(src, w: WRITE) => handle {\n if ((ts, wr)<(w.ts, w.wr)){\n /*(ts, wr, value) = (w.ts, w.wr, w.writeVal)*/\n ts = w.ts;\n wr = w.wr;\n value = w.writeVal;\n }\n trigger(PL_Send(src, ACK(w.rid)) -> pLink);\n println(s\"($self) Sendind ACK form $src -> rid: $rid\");\n }\n }\n\n pLink uponEvent {\n case PL_Deliver(src, v: VALUE) => handle {\n println(s\"($self) PL_Deliver VALUE form $src with acks: $acks and reading: $reading\");\n if (v.rid == rid) {\n /*val myVal: Option[Any] = v.value;*/\n readlist.update(src,(v.ts, v.wr, v.value));\n if(readlist.size > n/2){\n println(readlist.values);\n var maxts = readlist.maxBy(maplist => (maplist._2._1, maplist._2._2))._2._1;\n var rr= readlist.maxBy(maplist => (maplist._2._1, maplist._2._2))._2._2;\n readval = readlist.maxBy(maplist => (maplist._2._1, maplist._2._2))._2._3;\n println(s\"$maxts $rr $readval\");\n readlist = Map.empty;\n var bcastval: Option[Any] = None;\n if(reading){\n bcastval = readval;\n } else {\n rr = selfRank;\n maxts = maxts + 1;\n bcastval = writeval;\n }\n trigger(BEB_Broadcast(WRITE(rid, maxts, rr, bcastval)) -> beb);\n println(s\"($self) BEB_Broadcast WRITE -> $rid, $maxts, $rr, $bcastval\");\n }\n }\n }\n case PL_Deliver(src, v: ACK) => handle {\n println(s\"($self) PL_Deliver ACK from $src with acks: $acks and reading: $reading\");\n if (v.rid == rid) {\n acks = acks + 1;\n println(s\"($self) acks: $acks\");\n println(s\"($self) reading: $reading\");\n if(acks > n/2){\n acks = 0;\n if (reading){\n reading = false;\n trigger(AR_Read_Response(readval) -> nnar);\n println(s\"($self) AR_Read_Response -> $readval\");\n } else {\n trigger(AR_Write_Response() -> nnar);\n println(s\"($self) AR_Write_Response\");\n }\n }\n }\n }\n }\n}","user":"anonymous","dateUpdated":"2018-01-08T10:52:53+0000","config":{"lineNumbers":true,"editorSetting":{"language":"scala","editOnDblClick":false},"editorMode":"ace/mode/scala","colWidth":12,"fontSize":9,"results":{},"enabled":true,"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"defined class ReadImposeWriteConsultMajority
"}]},"apps":[],"jobName":"paragraph_1515161340379_-493672481","id":"20160830-120402_168996820","dateCreated":"2018-01-05T14:09:00+0000","dateStarted":"2018-01-08T10:52:53+0000","dateFinished":"2018-01-08T10:52:54+0000","status":"FINISHED","progressUpdateIntervalMs":500,"$$hashKey":"object:184"},{"text":" checkNNAR[ReadImposeWriteConsultMajority]();","user":"anonymous","dateUpdated":"2018-01-08T10:52:57+0000","config":{"editorSetting":{"language":"scala","editOnDblClick":false},"editorMode":"ace/mode/scala","colWidth":12,"fontSize":9,"results":{},"enabled":true,"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"
Your submission has been locally simulated and validated.

Click Here to view the output of the simulation.



Correction Results
PASSED Termination ✔: Every operation invoked by a correct process eventually completes
PASSED Atomicity/Linerizability ✔: Every read operation returns the value that was written most recently in a hypothetical global execution

Final Comments
**************
Congratulations! Your implementation of the 'NN Atomic Register' satisfies all properties!
A unique token has been generated for your submission right below. Please do not edit.

{\"gradingToken\":[45,45,45,45,45,66,69,71,73,78,32,80,71,80,32,77,69,83,83,65,71,69,45,45,45,45,45,10,86,101,114,115,105,111,110,58,32,66,67,80,71,32,118,49,46,53,53,10,10,104,81,73,77,65,57,79,116,77,118,84,69,98,74,49,102,65,82,65,65,117,118,109,53,107,105,88,118,87,49,104,120,114,56,112,120,88,75,114,52,85,72,90,102,57,102,108,75,115,67,101,85,85,105,111,115,115,86,122,111,113,118,108,67,10,78,57,109,82,113,70,113,113,105,102,107,65,88,105,116,85,104,121,100,99,115,79,103,109,110,66,90,77,104,116,104,101,79,55,122,69,99,43,85,112,72,87,77,115,50,71,68,115,87,76,106,83,55,56,119,90,81,120,115,107,72,82,115,104,10,103,122,101,83,105,71,43,110,88,112,90,79,56,114,77,54,98,100,113,83,99,90,51,108,86,69,108,74,73,71,115,113,111,73,121,116,86,99,112,57,113,88,53,71,66,74,98,55,117,90,68,107,66,105,84,65,86,90,120,54,71,73,114,90,10,54,112,88,110,73,84,55,103,76,90,77,109,47,85,112,112,80,68,120,83,112,74,97,84,107,115,85,78,88,53,56,82,103,65,116,78,52,54,53,79,71,103,55,104,89,121,88,103,72,65,115,72,120,122,72,113,52,114,43,87,110,83,74,52,10,85,55,50,52,48,68,110,51,47,75,70,56,71,78,101,65,114,88,80,110,120,103,115,97,89,111,114,99,71,51,115,48,84,97,83,50,72,71,72,51,98,84,56,79,51,80,84,122,69,43,104,68,53,51,78,122,120,103,99,102,89,112,101,103,10,106,121,81,97,121,104,73,81,107,54,48,115,112,75,109,97,101,119,86,90,115,112,87,77,77,106,113,56,49,70,76,114,75,79,49,56,53,54,43,109,113,105,52,70,52,90,112,122,74,116,100,121,90,50,89,54,43,43,78,113,89,86,49,43,10,73,48,69,51,102,104,47,73,54,98,80,90,112,108,102,70,78,75,78,108,85,117,71,68,104,73,48,120,107,109,76,98,112,103,47,114,47,110,90,112,110,54,110,56,88,114,77,101,85,72,116,66,72,65,103,52,52,82,113,80,106,121,104,103,10,52,43,97,69,57,70,73,57,49,69,122,117,113,81,52,86,79,87,107,118,89,84,97,111,80,77,43,113,43,90,73,99,100,69,97,83,98,84,110,47,105,48,65,43,90,78,121,101,80,112,109,82,109,109,47,54,56,99,112,98,54,120,82,85,10,74,72,101,99,78,111,106,78,118,74,83,102,70,85,77,119,101,106,119,89,122,75,106,65,69,121,115,43,118,84,68,68,122,105,74,110,108,90,99,122,111,115,71,104,103,87,70,105,79,112,88,117,87,57,121,111,110,89,71,113,43,66,113,43,10,87,43,73,43,66,100,83,83,53,85,57,79,66,116,107,78,85,104,72,84,54,117,112,111,81,99,119,78,79,119,114,101,106,82,78,98,83,116,82,52,57,89,82,54,120,43,118,48,117,67,98,118,101,52,81,104,79,75,76,119,53,83,116,102,10,69,117,50,54,73,115,51,110,87,113,117,76,121,100,89,48,89,89,86,114,53,77,119,71,119,108,89,108,67,104,106,114,100,82,104,65,74,52,76,68,65,82,54,107,106,116,103,118,109,105,57,102,105,120,106,119,77,71,43,75,90,109,72,83,10,119,65,115,66,114,107,111,74,110,115,97,72,75,86,85,76,71,51,103,121,122,69,104,89,49,99,48,56,89,117,107,102,79,69,114,53,102,117,52,84,79,121,99,69,49,48,108,120,68,107,73,76,77,114,51,85,97,76,112,77,57,102,90,70,10,84,120,116,119,43,105,89,99,109,48,101,67,109,120,119,50,77,71,79,82,121,55,82,98,112,111,67,115,51,108,111,111,85,83,78,110,107,106,116,83,65,101,120,113,111,49,110,83,43,79,120,72,66,65,82,104,89,77,90,68,70,69,83,116,10,82,111,105,72,77,67,73,81,72,101,49,75,48,116,116,99,117,56,47,85,84,48,110,80,120,86,69,76,99,106,112,67,48,53,121,55,77,74,98,55,105,122,84,65,112,98,112,77,109,55,53,106,108,53,75,90,70,113,70,51,56,53,72,116,10,87,68,114,122,54,54,81,77,77,56,68,73,101,48,72,99,48,113,119,81,122,71,68,53,43,74,110,107,47,97,48,57,86,105,69,49,84,99,55,69,77,113,101,104,120,90,55,68,73,115,65,116,55,76,118,69,53,48,75,104,71,105,47,53,10,49,50,70,111,79,120,86,50,49,83,49,98,114,81,118,69,113,65,61,61,10,61,117,114,102,47,10,45,45,45,45,45,69,78,68,32,80,71,80,32,77,69,83,83,65,71,69,45,45,45,45,45,10]}
res6: Boolean = true
"}]},"apps":[],"jobName":"paragraph_1515161340379_-493672481","id":"20160830-120430_1188854740","dateCreated":"2018-01-05T14:09:00+0000","dateStarted":"2018-01-08T10:52:57+0000","dateFinished":"2018-01-08T10:53:00+0000","status":"FINISHED","progressUpdateIntervalMs":500,"$$hashKey":"object:185"},{"dateUpdated":"2018-01-05T14:09:00+0000","config":{"editorSetting":{"language":"scala","editOnDblClick":false},"editorMode":"ace/mode/scala","colWidth":12,"fontSize":9,"results":{},"enabled":true,"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1515161340379_-493672481","id":"20160830-120658_2133406867","dateCreated":"2018-01-05T14:09:00+0000","status":"READY","errorMessage":"","progressUpdateIntervalMs":500,"$$hashKey":"object:186"}],"name":"Exercise-SharedMemory","id":"2D2GGQBQ9","angularObjects":{"2BKQCVH92:shared_process":[],"2CVXXPNWV:shared_process":[]},"config":{"looknfeel":"default","personalizedMode":"false"},"info":{}} -------------------------------------------------------------------------------- /Exercise SharedMemory/Exercise-SharedMemory.log: -------------------------------------------------------------------------------- 1 | SLF4J: Class path contains multiple SLF4J bindings. 2 | SLF4J: Found binding in [jar:file:/usr/zeppelin/interpreter/kompics/slf4j-log4j12-1.7.10.jar!/org/slf4j/impl/StaticLoggerBinder.class] 3 | SLF4J: Found binding in [jar:file:/usr/zeppelin/zeppelin-interpreter/target/lib/slf4j-log4j12-1.7.10.jar!/org/slf4j/impl/StaticLoggerBinder.class] 4 | SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. 5 | SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory] 6 | (TAddress(/192.168.2.1:1000)) WRITE: BEB_Broadcasting -> rid: 1 7 | (TAddress(/192.168.2.5:1000)) READ: BEB_Broadcasting -> rid: 1 reading: true 8 | (TAddress(/192.168.2.3:1000)) Sendind VALUE form TAddress(/192.168.2.1:1000) -> rid: 1 timestamp: 0 wr: 0 value: None 9 | (TAddress(/192.168.2.1:1000)) Sendind VALUE form TAddress(/192.168.2.1:1000) -> rid: 1 timestamp: 0 wr: 0 value: None 10 | (TAddress(/192.168.2.8:1000)) Sendind VALUE form TAddress(/192.168.2.1:1000) -> rid: 1 timestamp: 0 wr: 0 value: None 11 | (TAddress(/192.168.2.5:1000)) Sendind VALUE form TAddress(/192.168.2.1:1000) -> rid: 1 timestamp: 0 wr: 0 value: None 12 | (TAddress(/192.168.2.6:1000)) Sendind VALUE form TAddress(/192.168.2.1:1000) -> rid: 1 timestamp: 0 wr: 0 value: None 13 | (TAddress(/192.168.2.4:1000)) Sendind VALUE form TAddress(/192.168.2.1:1000) -> rid: 1 timestamp: 0 wr: 0 value: None 14 | (TAddress(/192.168.2.2:1000)) Sendind VALUE form TAddress(/192.168.2.1:1000) -> rid: 1 timestamp: 0 wr: 0 value: None 15 | (TAddress(/192.168.2.7:1000)) Sendind VALUE form TAddress(/192.168.2.1:1000) -> rid: 1 timestamp: 0 wr: 0 value: None 16 | (TAddress(/192.168.2.3:1000)) Sendind VALUE form TAddress(/192.168.2.5:1000) -> rid: 1 timestamp: 0 wr: 0 value: None 17 | (TAddress(/192.168.2.1:1000)) Sendind VALUE form TAddress(/192.168.2.5:1000) -> rid: 1 timestamp: 0 wr: 0 value: None 18 | (TAddress(/192.168.2.8:1000)) Sendind VALUE form TAddress(/192.168.2.5:1000) -> rid: 1 timestamp: 0 wr: 0 value: None 19 | (TAddress(/192.168.2.5:1000)) Sendind VALUE form TAddress(/192.168.2.5:1000) -> rid: 1 timestamp: 0 wr: 0 value: None 20 | (TAddress(/192.168.2.6:1000)) Sendind VALUE form TAddress(/192.168.2.5:1000) -> rid: 1 timestamp: 0 wr: 0 value: None 21 | (TAddress(/192.168.2.4:1000)) Sendind VALUE form TAddress(/192.168.2.5:1000) -> rid: 1 timestamp: 0 wr: 0 value: None 22 | (TAddress(/192.168.2.2:1000)) Sendind VALUE form TAddress(/192.168.2.5:1000) -> rid: 1 timestamp: 0 wr: 0 value: None 23 | (TAddress(/192.168.2.7:1000)) Sendind VALUE form TAddress(/192.168.2.5:1000) -> rid: 1 timestamp: 0 wr: 0 value: None 24 | (TAddress(/192.168.2.2:1000)) WRITE: BEB_Broadcasting -> rid: 1 25 | (TAddress(/192.168.2.1:1000)) PL_Deliver VALUE form TAddress(/192.168.2.3:1000) with acks: 0 and reading: false 26 | (TAddress(/192.168.2.1:1000)) PL_Deliver VALUE form TAddress(/192.168.2.1:1000) with acks: 0 and reading: false 27 | (TAddress(/192.168.2.1:1000)) PL_Deliver VALUE form TAddress(/192.168.2.8:1000) with acks: 0 and reading: false 28 | (TAddress(/192.168.2.1:1000)) PL_Deliver VALUE form TAddress(/192.168.2.5:1000) with acks: 0 and reading: false 29 | (TAddress(/192.168.2.1:1000)) PL_Deliver VALUE form TAddress(/192.168.2.6:1000) with acks: 0 and reading: false 30 | HashMap((0,0,None), (0,0,None), (0,0,None), (0,0,None), (0,0,None)) 31 | 0 0 None 32 | (TAddress(/192.168.2.1:1000)) BEB_Broadcast WRITE -> 1, 1, 1, Some(247983444) 33 | (TAddress(/192.168.2.1:1000)) PL_Deliver VALUE form TAddress(/192.168.2.4:1000) with acks: 0 and reading: false 34 | (TAddress(/192.168.2.1:1000)) PL_Deliver VALUE form TAddress(/192.168.2.2:1000) with acks: 0 and reading: false 35 | (TAddress(/192.168.2.1:1000)) PL_Deliver VALUE form TAddress(/192.168.2.7:1000) with acks: 0 and reading: false 36 | (TAddress(/192.168.2.6:1000)) READ: BEB_Broadcasting -> rid: 1 reading: true 37 | (TAddress(/192.168.2.5:1000)) PL_Deliver VALUE form TAddress(/192.168.2.3:1000) with acks: 0 and reading: true 38 | (TAddress(/192.168.2.5:1000)) PL_Deliver VALUE form TAddress(/192.168.2.1:1000) with acks: 0 and reading: true 39 | (TAddress(/192.168.2.5:1000)) PL_Deliver VALUE form TAddress(/192.168.2.8:1000) with acks: 0 and reading: true 40 | (TAddress(/192.168.2.5:1000)) PL_Deliver VALUE form TAddress(/192.168.2.5:1000) with acks: 0 and reading: true 41 | (TAddress(/192.168.2.5:1000)) PL_Deliver VALUE form TAddress(/192.168.2.6:1000) with acks: 0 and reading: true 42 | HashMap((0,0,None), (0,0,None), (0,0,None), (0,0,None), (0,0,None)) 43 | 0 0 None 44 | (TAddress(/192.168.2.5:1000)) BEB_Broadcast WRITE -> 1, 0, 0, None 45 | (TAddress(/192.168.2.5:1000)) PL_Deliver VALUE form TAddress(/192.168.2.4:1000) with acks: 0 and reading: true 46 | (TAddress(/192.168.2.5:1000)) PL_Deliver VALUE form TAddress(/192.168.2.2:1000) with acks: 0 and reading: true 47 | (TAddress(/192.168.2.5:1000)) PL_Deliver VALUE form TAddress(/192.168.2.7:1000) with acks: 0 and reading: true 48 | (TAddress(/192.168.2.3:1000)) Sendind VALUE form TAddress(/192.168.2.2:1000) -> rid: 1 timestamp: 0 wr: 0 value: None 49 | (TAddress(/192.168.2.1:1000)) Sendind VALUE form TAddress(/192.168.2.2:1000) -> rid: 1 timestamp: 0 wr: 0 value: None 50 | (TAddress(/192.168.2.8:1000)) Sendind VALUE form TAddress(/192.168.2.2:1000) -> rid: 1 timestamp: 0 wr: 0 value: None 51 | (TAddress(/192.168.2.5:1000)) Sendind VALUE form TAddress(/192.168.2.2:1000) -> rid: 1 timestamp: 0 wr: 0 value: None 52 | (TAddress(/192.168.2.6:1000)) Sendind VALUE form TAddress(/192.168.2.2:1000) -> rid: 1 timestamp: 0 wr: 0 value: None 53 | (TAddress(/192.168.2.4:1000)) Sendind VALUE form TAddress(/192.168.2.2:1000) -> rid: 1 timestamp: 0 wr: 0 value: None 54 | (TAddress(/192.168.2.2:1000)) Sendind VALUE form TAddress(/192.168.2.2:1000) -> rid: 1 timestamp: 0 wr: 0 value: None 55 | (TAddress(/192.168.2.7:1000)) Sendind VALUE form TAddress(/192.168.2.2:1000) -> rid: 1 timestamp: 0 wr: 0 value: None 56 | (TAddress(/192.168.2.3:1000)) Sendind ACK form TAddress(/192.168.2.1:1000) -> rid: 0 57 | (TAddress(/192.168.2.1:1000)) Sendind ACK form TAddress(/192.168.2.1:1000) -> rid: 1 58 | (TAddress(/192.168.2.8:1000)) Sendind ACK form TAddress(/192.168.2.1:1000) -> rid: 0 59 | (TAddress(/192.168.2.5:1000)) Sendind ACK form TAddress(/192.168.2.1:1000) -> rid: 1 60 | (TAddress(/192.168.2.6:1000)) Sendind ACK form TAddress(/192.168.2.1:1000) -> rid: 1 61 | (TAddress(/192.168.2.4:1000)) Sendind ACK form TAddress(/192.168.2.1:1000) -> rid: 0 62 | (TAddress(/192.168.2.2:1000)) Sendind ACK form TAddress(/192.168.2.1:1000) -> rid: 1 63 | (TAddress(/192.168.2.7:1000)) Sendind ACK form TAddress(/192.168.2.1:1000) -> rid: 0 64 | (TAddress(/192.168.2.3:1000)) Sendind VALUE form TAddress(/192.168.2.6:1000) -> rid: 1 timestamp: 1 wr: 1 value: Some(247983444) 65 | (TAddress(/192.168.2.1:1000)) Sendind VALUE form TAddress(/192.168.2.6:1000) -> rid: 1 timestamp: 1 wr: 1 value: Some(247983444) 66 | (TAddress(/192.168.2.8:1000)) Sendind VALUE form TAddress(/192.168.2.6:1000) -> rid: 1 timestamp: 1 wr: 1 value: Some(247983444) 67 | (TAddress(/192.168.2.5:1000)) Sendind VALUE form TAddress(/192.168.2.6:1000) -> rid: 1 timestamp: 1 wr: 1 value: Some(247983444) 68 | (TAddress(/192.168.2.6:1000)) Sendind VALUE form TAddress(/192.168.2.6:1000) -> rid: 1 timestamp: 1 wr: 1 value: Some(247983444) 69 | (TAddress(/192.168.2.4:1000)) Sendind VALUE form TAddress(/192.168.2.6:1000) -> rid: 1 timestamp: 1 wr: 1 value: Some(247983444) 70 | (TAddress(/192.168.2.2:1000)) Sendind VALUE form TAddress(/192.168.2.6:1000) -> rid: 1 timestamp: 1 wr: 1 value: Some(247983444) 71 | (TAddress(/192.168.2.7:1000)) Sendind VALUE form TAddress(/192.168.2.6:1000) -> rid: 1 timestamp: 1 wr: 1 value: Some(247983444) 72 | (TAddress(/192.168.2.3:1000)) Sendind ACK form TAddress(/192.168.2.5:1000) -> rid: 0 73 | (TAddress(/192.168.2.1:1000)) Sendind ACK form TAddress(/192.168.2.5:1000) -> rid: 1 74 | (TAddress(/192.168.2.8:1000)) Sendind ACK form TAddress(/192.168.2.5:1000) -> rid: 0 75 | (TAddress(/192.168.2.5:1000)) Sendind ACK form TAddress(/192.168.2.5:1000) -> rid: 1 76 | (TAddress(/192.168.2.6:1000)) Sendind ACK form TAddress(/192.168.2.5:1000) -> rid: 1 77 | (TAddress(/192.168.2.4:1000)) Sendind ACK form TAddress(/192.168.2.5:1000) -> rid: 0 78 | (TAddress(/192.168.2.2:1000)) Sendind ACK form TAddress(/192.168.2.5:1000) -> rid: 1 79 | (TAddress(/192.168.2.7:1000)) Sendind ACK form TAddress(/192.168.2.5:1000) -> rid: 0 80 | (TAddress(/192.168.2.3:1000)) WRITE: BEB_Broadcasting -> rid: 1 81 | (TAddress(/192.168.2.2:1000)) PL_Deliver VALUE form TAddress(/192.168.2.3:1000) with acks: 0 and reading: false 82 | (TAddress(/192.168.2.1:1000)) PL_Deliver ACK from TAddress(/192.168.2.3:1000) with acks: 0 and reading: false 83 | (TAddress(/192.168.2.1:1000)) acks: 1 84 | (TAddress(/192.168.2.1:1000)) reading: false 85 | (TAddress(/192.168.2.2:1000)) PL_Deliver VALUE form TAddress(/192.168.2.1:1000) with acks: 0 and reading: false 86 | (TAddress(/192.168.2.1:1000)) PL_Deliver ACK from TAddress(/192.168.2.1:1000) with acks: 1 and reading: false 87 | (TAddress(/192.168.2.1:1000)) acks: 2 88 | (TAddress(/192.168.2.1:1000)) reading: false 89 | (TAddress(/192.168.2.2:1000)) PL_Deliver VALUE form TAddress(/192.168.2.8:1000) with acks: 0 and reading: false 90 | (TAddress(/192.168.2.1:1000)) PL_Deliver ACK from TAddress(/192.168.2.8:1000) with acks: 2 and reading: false 91 | (TAddress(/192.168.2.1:1000)) acks: 3 92 | (TAddress(/192.168.2.1:1000)) reading: false 93 | (TAddress(/192.168.2.2:1000)) PL_Deliver VALUE form TAddress(/192.168.2.5:1000) with acks: 0 and reading: false 94 | (TAddress(/192.168.2.1:1000)) PL_Deliver ACK from TAddress(/192.168.2.5:1000) with acks: 3 and reading: false 95 | (TAddress(/192.168.2.1:1000)) acks: 4 96 | (TAddress(/192.168.2.1:1000)) reading: false 97 | (TAddress(/192.168.2.2:1000)) PL_Deliver VALUE form TAddress(/192.168.2.6:1000) with acks: 0 and reading: false 98 | HashMap((0,0,None), (0,0,None), (0,0,None), (0,0,None), (0,0,None)) 99 | 0 0 None 100 | (TAddress(/192.168.2.2:1000)) BEB_Broadcast WRITE -> 1, 1, 2, Some(-1038318701) 101 | (TAddress(/192.168.2.1:1000)) PL_Deliver ACK from TAddress(/192.168.2.6:1000) with acks: 4 and reading: false 102 | (TAddress(/192.168.2.1:1000)) acks: 5 103 | (TAddress(/192.168.2.1:1000)) reading: false 104 | (TAddress(/192.168.2.1:1000)) AR_Write_Response 105 | (TAddress(/192.168.2.2:1000)) PL_Deliver VALUE form TAddress(/192.168.2.4:1000) with acks: 0 and reading: false 106 | (TAddress(/192.168.2.1:1000)) PL_Deliver ACK from TAddress(/192.168.2.4:1000) with acks: 0 and reading: false 107 | (TAddress(/192.168.2.1:1000)) acks: 1 108 | (TAddress(/192.168.2.1:1000)) reading: false 109 | (TAddress(/192.168.2.2:1000)) PL_Deliver VALUE form TAddress(/192.168.2.2:1000) with acks: 0 and reading: false 110 | (TAddress(/192.168.2.1:1000)) PL_Deliver ACK from TAddress(/192.168.2.2:1000) with acks: 1 and reading: false 111 | (TAddress(/192.168.2.1:1000)) acks: 2 112 | (TAddress(/192.168.2.1:1000)) reading: false 113 | (TAddress(/192.168.2.2:1000)) PL_Deliver VALUE form TAddress(/192.168.2.7:1000) with acks: 0 and reading: false 114 | (TAddress(/192.168.2.1:1000)) PL_Deliver ACK from TAddress(/192.168.2.7:1000) with acks: 2 and reading: false 115 | (TAddress(/192.168.2.1:1000)) acks: 3 116 | (TAddress(/192.168.2.1:1000)) reading: false 117 | (TAddress(/192.168.2.7:1000)) READ: BEB_Broadcasting -> rid: 1 reading: true 118 | (TAddress(/192.168.2.6:1000)) PL_Deliver VALUE form TAddress(/192.168.2.3:1000) with acks: 0 and reading: true 119 | (TAddress(/192.168.2.5:1000)) PL_Deliver ACK from TAddress(/192.168.2.3:1000) with acks: 0 and reading: true 120 | (TAddress(/192.168.2.5:1000)) acks: 1 121 | (TAddress(/192.168.2.5:1000)) reading: true 122 | (TAddress(/192.168.2.6:1000)) PL_Deliver VALUE form TAddress(/192.168.2.1:1000) with acks: 0 and reading: true 123 | (TAddress(/192.168.2.5:1000)) PL_Deliver ACK from TAddress(/192.168.2.1:1000) with acks: 1 and reading: true 124 | (TAddress(/192.168.2.5:1000)) acks: 2 125 | (TAddress(/192.168.2.5:1000)) reading: true 126 | (TAddress(/192.168.2.6:1000)) PL_Deliver VALUE form TAddress(/192.168.2.8:1000) with acks: 0 and reading: true 127 | (TAddress(/192.168.2.5:1000)) PL_Deliver ACK from TAddress(/192.168.2.8:1000) with acks: 2 and reading: true 128 | (TAddress(/192.168.2.5:1000)) acks: 3 129 | (TAddress(/192.168.2.5:1000)) reading: true 130 | (TAddress(/192.168.2.6:1000)) PL_Deliver VALUE form TAddress(/192.168.2.5:1000) with acks: 0 and reading: true 131 | (TAddress(/192.168.2.5:1000)) PL_Deliver ACK from TAddress(/192.168.2.5:1000) with acks: 3 and reading: true 132 | (TAddress(/192.168.2.5:1000)) acks: 4 133 | (TAddress(/192.168.2.5:1000)) reading: true 134 | (TAddress(/192.168.2.6:1000)) PL_Deliver VALUE form TAddress(/192.168.2.6:1000) with acks: 0 and reading: true 135 | HashMap((1,1,Some(247983444)), (1,1,Some(247983444)), (1,1,Some(247983444)), (1,1,Some(247983444)), (1,1,Some(247983444))) 136 | 1 1 Some(247983444) 137 | (TAddress(/192.168.2.6:1000)) BEB_Broadcast WRITE -> 1, 1, 1, Some(247983444) 138 | (TAddress(/192.168.2.5:1000)) PL_Deliver ACK from TAddress(/192.168.2.6:1000) with acks: 4 and reading: true 139 | (TAddress(/192.168.2.5:1000)) acks: 5 140 | (TAddress(/192.168.2.5:1000)) reading: true 141 | (TAddress(/192.168.2.5:1000)) AR_Read_Response -> None 142 | (TAddress(/192.168.2.6:1000)) PL_Deliver VALUE form TAddress(/192.168.2.4:1000) with acks: 0 and reading: true 143 | (TAddress(/192.168.2.5:1000)) PL_Deliver ACK from TAddress(/192.168.2.4:1000) with acks: 0 and reading: false 144 | (TAddress(/192.168.2.5:1000)) acks: 1 145 | (TAddress(/192.168.2.5:1000)) reading: false 146 | (TAddress(/192.168.2.6:1000)) PL_Deliver VALUE form TAddress(/192.168.2.2:1000) with acks: 0 and reading: true 147 | (TAddress(/192.168.2.5:1000)) PL_Deliver ACK from TAddress(/192.168.2.2:1000) with acks: 1 and reading: false 148 | (TAddress(/192.168.2.5:1000)) acks: 2 149 | (TAddress(/192.168.2.5:1000)) reading: false 150 | (TAddress(/192.168.2.6:1000)) PL_Deliver VALUE form TAddress(/192.168.2.7:1000) with acks: 0 and reading: true 151 | (TAddress(/192.168.2.5:1000)) PL_Deliver ACK from TAddress(/192.168.2.7:1000) with acks: 2 and reading: false 152 | (TAddress(/192.168.2.5:1000)) acks: 3 153 | (TAddress(/192.168.2.5:1000)) reading: false 154 | (TAddress(/192.168.2.3:1000)) Sendind VALUE form TAddress(/192.168.2.3:1000) -> rid: 1 timestamp: 1 wr: 1 value: Some(247983444) 155 | (TAddress(/192.168.2.1:1000)) Sendind VALUE form TAddress(/192.168.2.3:1000) -> rid: 1 timestamp: 1 wr: 1 value: Some(247983444) 156 | (TAddress(/192.168.2.8:1000)) Sendind VALUE form TAddress(/192.168.2.3:1000) -> rid: 1 timestamp: 1 wr: 1 value: Some(247983444) 157 | (TAddress(/192.168.2.5:1000)) Sendind VALUE form TAddress(/192.168.2.3:1000) -> rid: 1 timestamp: 1 wr: 1 value: Some(247983444) 158 | (TAddress(/192.168.2.6:1000)) Sendind VALUE form TAddress(/192.168.2.3:1000) -> rid: 1 timestamp: 1 wr: 1 value: Some(247983444) 159 | (TAddress(/192.168.2.4:1000)) Sendind VALUE form TAddress(/192.168.2.3:1000) -> rid: 1 timestamp: 1 wr: 1 value: Some(247983444) 160 | (TAddress(/192.168.2.2:1000)) Sendind VALUE form TAddress(/192.168.2.3:1000) -> rid: 1 timestamp: 1 wr: 1 value: Some(247983444) 161 | (TAddress(/192.168.2.7:1000)) Sendind VALUE form TAddress(/192.168.2.3:1000) -> rid: 1 timestamp: 1 wr: 1 value: Some(247983444) 162 | (TAddress(/192.168.2.3:1000)) Sendind ACK form TAddress(/192.168.2.2:1000) -> rid: 1 163 | (TAddress(/192.168.2.1:1000)) Sendind ACK form TAddress(/192.168.2.2:1000) -> rid: 1 164 | (TAddress(/192.168.2.8:1000)) Sendind ACK form TAddress(/192.168.2.2:1000) -> rid: 0 165 | (TAddress(/192.168.2.5:1000)) Sendind ACK form TAddress(/192.168.2.2:1000) -> rid: 1 166 | (TAddress(/192.168.2.6:1000)) Sendind ACK form TAddress(/192.168.2.2:1000) -> rid: 1 167 | (TAddress(/192.168.2.4:1000)) Sendind ACK form TAddress(/192.168.2.2:1000) -> rid: 0 168 | (TAddress(/192.168.2.2:1000)) Sendind ACK form TAddress(/192.168.2.2:1000) -> rid: 1 169 | (TAddress(/192.168.2.7:1000)) Sendind ACK form TAddress(/192.168.2.2:1000) -> rid: 1 170 | (TAddress(/192.168.2.3:1000)) Sendind VALUE form TAddress(/192.168.2.7:1000) -> rid: 1 timestamp: 1 wr: 2 value: Some(-1038318701) 171 | (TAddress(/192.168.2.1:1000)) Sendind VALUE form TAddress(/192.168.2.7:1000) -> rid: 1 timestamp: 1 wr: 2 value: Some(-1038318701) 172 | (TAddress(/192.168.2.8:1000)) Sendind VALUE form TAddress(/192.168.2.7:1000) -> rid: 1 timestamp: 1 wr: 2 value: Some(-1038318701) 173 | (TAddress(/192.168.2.5:1000)) Sendind VALUE form TAddress(/192.168.2.7:1000) -> rid: 1 timestamp: 1 wr: 2 value: Some(-1038318701) 174 | (TAddress(/192.168.2.6:1000)) Sendind VALUE form TAddress(/192.168.2.7:1000) -> rid: 1 timestamp: 1 wr: 2 value: Some(-1038318701) 175 | (TAddress(/192.168.2.4:1000)) Sendind VALUE form TAddress(/192.168.2.7:1000) -> rid: 1 timestamp: 1 wr: 2 value: Some(-1038318701) 176 | (TAddress(/192.168.2.2:1000)) Sendind VALUE form TAddress(/192.168.2.7:1000) -> rid: 1 timestamp: 1 wr: 2 value: Some(-1038318701) 177 | (TAddress(/192.168.2.7:1000)) Sendind VALUE form TAddress(/192.168.2.7:1000) -> rid: 1 timestamp: 1 wr: 2 value: Some(-1038318701) 178 | (TAddress(/192.168.2.3:1000)) Sendind ACK form TAddress(/192.168.2.6:1000) -> rid: 1 179 | (TAddress(/192.168.2.1:1000)) Sendind ACK form TAddress(/192.168.2.6:1000) -> rid: 1 180 | (TAddress(/192.168.2.8:1000)) Sendind ACK form TAddress(/192.168.2.6:1000) -> rid: 0 181 | (TAddress(/192.168.2.5:1000)) Sendind ACK form TAddress(/192.168.2.6:1000) -> rid: 1 182 | (TAddress(/192.168.2.6:1000)) Sendind ACK form TAddress(/192.168.2.6:1000) -> rid: 1 183 | (TAddress(/192.168.2.4:1000)) Sendind ACK form TAddress(/192.168.2.6:1000) -> rid: 0 184 | (TAddress(/192.168.2.2:1000)) Sendind ACK form TAddress(/192.168.2.6:1000) -> rid: 1 185 | (TAddress(/192.168.2.7:1000)) Sendind ACK form TAddress(/192.168.2.6:1000) -> rid: 1 186 | (TAddress(/192.168.2.4:1000)) WRITE: BEB_Broadcasting -> rid: 1 187 | (TAddress(/192.168.2.3:1000)) PL_Deliver VALUE form TAddress(/192.168.2.3:1000) with acks: 0 and reading: false 188 | (TAddress(/192.168.2.2:1000)) PL_Deliver ACK from TAddress(/192.168.2.3:1000) with acks: 0 and reading: false 189 | (TAddress(/192.168.2.2:1000)) acks: 1 190 | (TAddress(/192.168.2.2:1000)) reading: false 191 | (TAddress(/192.168.2.3:1000)) PL_Deliver VALUE form TAddress(/192.168.2.1:1000) with acks: 0 and reading: false 192 | (TAddress(/192.168.2.2:1000)) PL_Deliver ACK from TAddress(/192.168.2.1:1000) with acks: 1 and reading: false 193 | (TAddress(/192.168.2.2:1000)) acks: 2 194 | (TAddress(/192.168.2.2:1000)) reading: false 195 | (TAddress(/192.168.2.3:1000)) PL_Deliver VALUE form TAddress(/192.168.2.8:1000) with acks: 0 and reading: false 196 | (TAddress(/192.168.2.2:1000)) PL_Deliver ACK from TAddress(/192.168.2.8:1000) with acks: 2 and reading: false 197 | (TAddress(/192.168.2.2:1000)) acks: 3 198 | (TAddress(/192.168.2.2:1000)) reading: false 199 | (TAddress(/192.168.2.3:1000)) PL_Deliver VALUE form TAddress(/192.168.2.5:1000) with acks: 0 and reading: false 200 | (TAddress(/192.168.2.2:1000)) PL_Deliver ACK from TAddress(/192.168.2.5:1000) with acks: 3 and reading: false 201 | (TAddress(/192.168.2.2:1000)) acks: 4 202 | (TAddress(/192.168.2.2:1000)) reading: false 203 | (TAddress(/192.168.2.3:1000)) PL_Deliver VALUE form TAddress(/192.168.2.6:1000) with acks: 0 and reading: false 204 | HashMap((1,1,Some(247983444)), (1,1,Some(247983444)), (1,1,Some(247983444)), (1,1,Some(247983444)), (1,1,Some(247983444))) 205 | 1 1 Some(247983444) 206 | (TAddress(/192.168.2.3:1000)) BEB_Broadcast WRITE -> 1, 2, 3, Some(-988758023) 207 | (TAddress(/192.168.2.2:1000)) PL_Deliver ACK from TAddress(/192.168.2.6:1000) with acks: 4 and reading: false 208 | (TAddress(/192.168.2.2:1000)) acks: 5 209 | (TAddress(/192.168.2.2:1000)) reading: false 210 | (TAddress(/192.168.2.2:1000)) AR_Write_Response 211 | (TAddress(/192.168.2.3:1000)) PL_Deliver VALUE form TAddress(/192.168.2.4:1000) with acks: 0 and reading: false 212 | (TAddress(/192.168.2.2:1000)) PL_Deliver ACK from TAddress(/192.168.2.4:1000) with acks: 0 and reading: false 213 | (TAddress(/192.168.2.2:1000)) acks: 1 214 | (TAddress(/192.168.2.2:1000)) reading: false 215 | (TAddress(/192.168.2.3:1000)) PL_Deliver VALUE form TAddress(/192.168.2.2:1000) with acks: 0 and reading: false 216 | (TAddress(/192.168.2.2:1000)) PL_Deliver ACK from TAddress(/192.168.2.2:1000) with acks: 1 and reading: false 217 | (TAddress(/192.168.2.2:1000)) acks: 2 218 | (TAddress(/192.168.2.2:1000)) reading: false 219 | (TAddress(/192.168.2.3:1000)) PL_Deliver VALUE form TAddress(/192.168.2.7:1000) with acks: 0 and reading: false 220 | (TAddress(/192.168.2.2:1000)) PL_Deliver ACK from TAddress(/192.168.2.7:1000) with acks: 2 and reading: false 221 | (TAddress(/192.168.2.2:1000)) acks: 3 222 | (TAddress(/192.168.2.2:1000)) reading: false 223 | (TAddress(/192.168.2.8:1000)) READ: BEB_Broadcasting -> rid: 1 reading: true 224 | (TAddress(/192.168.2.7:1000)) PL_Deliver VALUE form TAddress(/192.168.2.3:1000) with acks: 0 and reading: true 225 | (TAddress(/192.168.2.6:1000)) PL_Deliver ACK from TAddress(/192.168.2.3:1000) with acks: 0 and reading: true 226 | (TAddress(/192.168.2.6:1000)) acks: 1 227 | (TAddress(/192.168.2.6:1000)) reading: true 228 | (TAddress(/192.168.2.7:1000)) PL_Deliver VALUE form TAddress(/192.168.2.1:1000) with acks: 0 and reading: true 229 | (TAddress(/192.168.2.6:1000)) PL_Deliver ACK from TAddress(/192.168.2.1:1000) with acks: 1 and reading: true 230 | (TAddress(/192.168.2.6:1000)) acks: 2 231 | (TAddress(/192.168.2.6:1000)) reading: true 232 | (TAddress(/192.168.2.7:1000)) PL_Deliver VALUE form TAddress(/192.168.2.8:1000) with acks: 0 and reading: true 233 | (TAddress(/192.168.2.6:1000)) PL_Deliver ACK from TAddress(/192.168.2.8:1000) with acks: 2 and reading: true 234 | (TAddress(/192.168.2.6:1000)) acks: 3 235 | (TAddress(/192.168.2.6:1000)) reading: true 236 | (TAddress(/192.168.2.7:1000)) PL_Deliver VALUE form TAddress(/192.168.2.5:1000) with acks: 0 and reading: true 237 | (TAddress(/192.168.2.6:1000)) PL_Deliver ACK from TAddress(/192.168.2.5:1000) with acks: 3 and reading: true 238 | (TAddress(/192.168.2.6:1000)) acks: 4 239 | (TAddress(/192.168.2.6:1000)) reading: true 240 | (TAddress(/192.168.2.7:1000)) PL_Deliver VALUE form TAddress(/192.168.2.6:1000) with acks: 0 and reading: true 241 | HashMap((1,2,Some(-1038318701)), (1,2,Some(-1038318701)), (1,2,Some(-1038318701)), (1,2,Some(-1038318701)), (1,2,Some(-1038318701))) 242 | 1 2 Some(-1038318701) 243 | (TAddress(/192.168.2.7:1000)) BEB_Broadcast WRITE -> 1, 1, 2, Some(-1038318701) 244 | (TAddress(/192.168.2.6:1000)) PL_Deliver ACK from TAddress(/192.168.2.6:1000) with acks: 4 and reading: true 245 | (TAddress(/192.168.2.6:1000)) acks: 5 246 | (TAddress(/192.168.2.6:1000)) reading: true 247 | (TAddress(/192.168.2.6:1000)) AR_Read_Response -> Some(247983444) 248 | (TAddress(/192.168.2.7:1000)) PL_Deliver VALUE form TAddress(/192.168.2.4:1000) with acks: 0 and reading: true 249 | (TAddress(/192.168.2.6:1000)) PL_Deliver ACK from TAddress(/192.168.2.4:1000) with acks: 0 and reading: false 250 | (TAddress(/192.168.2.6:1000)) acks: 1 251 | (TAddress(/192.168.2.6:1000)) reading: false 252 | (TAddress(/192.168.2.7:1000)) PL_Deliver VALUE form TAddress(/192.168.2.2:1000) with acks: 0 and reading: true 253 | (TAddress(/192.168.2.6:1000)) PL_Deliver ACK from TAddress(/192.168.2.2:1000) with acks: 1 and reading: false 254 | (TAddress(/192.168.2.6:1000)) acks: 2 255 | (TAddress(/192.168.2.6:1000)) reading: false 256 | (TAddress(/192.168.2.7:1000)) PL_Deliver VALUE form TAddress(/192.168.2.7:1000) with acks: 0 and reading: true 257 | (TAddress(/192.168.2.6:1000)) PL_Deliver ACK from TAddress(/192.168.2.7:1000) with acks: 2 and reading: false 258 | (TAddress(/192.168.2.6:1000)) acks: 3 259 | (TAddress(/192.168.2.6:1000)) reading: false 260 | (TAddress(/192.168.2.3:1000)) Sendind VALUE form TAddress(/192.168.2.4:1000) -> rid: 1 timestamp: 1 wr: 2 value: Some(-1038318701) 261 | (TAddress(/192.168.2.1:1000)) Sendind VALUE form TAddress(/192.168.2.4:1000) -> rid: 1 timestamp: 1 wr: 2 value: Some(-1038318701) 262 | (TAddress(/192.168.2.8:1000)) Sendind VALUE form TAddress(/192.168.2.4:1000) -> rid: 1 timestamp: 1 wr: 2 value: Some(-1038318701) 263 | (TAddress(/192.168.2.5:1000)) Sendind VALUE form TAddress(/192.168.2.4:1000) -> rid: 1 timestamp: 1 wr: 2 value: Some(-1038318701) 264 | (TAddress(/192.168.2.6:1000)) Sendind VALUE form TAddress(/192.168.2.4:1000) -> rid: 1 timestamp: 1 wr: 2 value: Some(-1038318701) 265 | (TAddress(/192.168.2.4:1000)) Sendind VALUE form TAddress(/192.168.2.4:1000) -> rid: 1 timestamp: 1 wr: 2 value: Some(-1038318701) 266 | (TAddress(/192.168.2.2:1000)) Sendind VALUE form TAddress(/192.168.2.4:1000) -> rid: 1 timestamp: 1 wr: 2 value: Some(-1038318701) 267 | (TAddress(/192.168.2.7:1000)) Sendind VALUE form TAddress(/192.168.2.4:1000) -> rid: 1 timestamp: 1 wr: 2 value: Some(-1038318701) 268 | (TAddress(/192.168.2.3:1000)) Sendind ACK form TAddress(/192.168.2.3:1000) -> rid: 1 269 | (TAddress(/192.168.2.1:1000)) Sendind ACK form TAddress(/192.168.2.3:1000) -> rid: 1 270 | (TAddress(/192.168.2.8:1000)) Sendind ACK form TAddress(/192.168.2.3:1000) -> rid: 1 271 | (TAddress(/192.168.2.5:1000)) Sendind ACK form TAddress(/192.168.2.3:1000) -> rid: 1 272 | (TAddress(/192.168.2.6:1000)) Sendind ACK form TAddress(/192.168.2.3:1000) -> rid: 1 273 | (TAddress(/192.168.2.4:1000)) Sendind ACK form TAddress(/192.168.2.3:1000) -> rid: 1 274 | (TAddress(/192.168.2.2:1000)) Sendind ACK form TAddress(/192.168.2.3:1000) -> rid: 1 275 | (TAddress(/192.168.2.7:1000)) Sendind ACK form TAddress(/192.168.2.3:1000) -> rid: 1 276 | (TAddress(/192.168.2.3:1000)) Sendind VALUE form TAddress(/192.168.2.8:1000) -> rid: 1 timestamp: 2 wr: 3 value: Some(-988758023) 277 | (TAddress(/192.168.2.1:1000)) Sendind VALUE form TAddress(/192.168.2.8:1000) -> rid: 1 timestamp: 2 wr: 3 value: Some(-988758023) 278 | (TAddress(/192.168.2.8:1000)) Sendind VALUE form TAddress(/192.168.2.8:1000) -> rid: 1 timestamp: 2 wr: 3 value: Some(-988758023) 279 | (TAddress(/192.168.2.5:1000)) Sendind VALUE form TAddress(/192.168.2.8:1000) -> rid: 1 timestamp: 2 wr: 3 value: Some(-988758023) 280 | (TAddress(/192.168.2.6:1000)) Sendind VALUE form TAddress(/192.168.2.8:1000) -> rid: 1 timestamp: 2 wr: 3 value: Some(-988758023) 281 | (TAddress(/192.168.2.4:1000)) Sendind VALUE form TAddress(/192.168.2.8:1000) -> rid: 1 timestamp: 2 wr: 3 value: Some(-988758023) 282 | (TAddress(/192.168.2.2:1000)) Sendind VALUE form TAddress(/192.168.2.8:1000) -> rid: 1 timestamp: 2 wr: 3 value: Some(-988758023) 283 | (TAddress(/192.168.2.7:1000)) Sendind VALUE form TAddress(/192.168.2.8:1000) -> rid: 1 timestamp: 2 wr: 3 value: Some(-988758023) 284 | (TAddress(/192.168.2.3:1000)) Sendind ACK form TAddress(/192.168.2.7:1000) -> rid: 1 285 | (TAddress(/192.168.2.1:1000)) Sendind ACK form TAddress(/192.168.2.7:1000) -> rid: 1 286 | (TAddress(/192.168.2.8:1000)) Sendind ACK form TAddress(/192.168.2.7:1000) -> rid: 1 287 | (TAddress(/192.168.2.5:1000)) Sendind ACK form TAddress(/192.168.2.7:1000) -> rid: 1 288 | (TAddress(/192.168.2.6:1000)) Sendind ACK form TAddress(/192.168.2.7:1000) -> rid: 1 289 | (TAddress(/192.168.2.4:1000)) Sendind ACK form TAddress(/192.168.2.7:1000) -> rid: 1 290 | (TAddress(/192.168.2.2:1000)) Sendind ACK form TAddress(/192.168.2.7:1000) -> rid: 1 291 | (TAddress(/192.168.2.7:1000)) Sendind ACK form TAddress(/192.168.2.7:1000) -> rid: 1 292 | (TAddress(/192.168.2.4:1000)) PL_Deliver VALUE form TAddress(/192.168.2.3:1000) with acks: 0 and reading: false 293 | (TAddress(/192.168.2.3:1000)) PL_Deliver ACK from TAddress(/192.168.2.3:1000) with acks: 0 and reading: false 294 | (TAddress(/192.168.2.3:1000)) acks: 1 295 | (TAddress(/192.168.2.3:1000)) reading: false 296 | (TAddress(/192.168.2.4:1000)) PL_Deliver VALUE form TAddress(/192.168.2.1:1000) with acks: 0 and reading: false 297 | (TAddress(/192.168.2.3:1000)) PL_Deliver ACK from TAddress(/192.168.2.1:1000) with acks: 1 and reading: false 298 | (TAddress(/192.168.2.3:1000)) acks: 2 299 | (TAddress(/192.168.2.3:1000)) reading: false 300 | (TAddress(/192.168.2.4:1000)) PL_Deliver VALUE form TAddress(/192.168.2.8:1000) with acks: 0 and reading: false 301 | (TAddress(/192.168.2.3:1000)) PL_Deliver ACK from TAddress(/192.168.2.8:1000) with acks: 2 and reading: false 302 | (TAddress(/192.168.2.3:1000)) acks: 3 303 | (TAddress(/192.168.2.3:1000)) reading: false 304 | (TAddress(/192.168.2.4:1000)) PL_Deliver VALUE form TAddress(/192.168.2.5:1000) with acks: 0 and reading: false 305 | (TAddress(/192.168.2.3:1000)) PL_Deliver ACK from TAddress(/192.168.2.5:1000) with acks: 3 and reading: false 306 | (TAddress(/192.168.2.3:1000)) acks: 4 307 | (TAddress(/192.168.2.3:1000)) reading: false 308 | (TAddress(/192.168.2.4:1000)) PL_Deliver VALUE form TAddress(/192.168.2.6:1000) with acks: 0 and reading: false 309 | HashMap((1,2,Some(-1038318701)), (1,2,Some(-1038318701)), (1,2,Some(-1038318701)), (1,2,Some(-1038318701)), (1,2,Some(-1038318701))) 310 | 1 2 Some(-1038318701) 311 | (TAddress(/192.168.2.4:1000)) BEB_Broadcast WRITE -> 1, 2, 4, Some(-1285954666) 312 | (TAddress(/192.168.2.3:1000)) PL_Deliver ACK from TAddress(/192.168.2.6:1000) with acks: 4 and reading: false 313 | (TAddress(/192.168.2.3:1000)) acks: 5 314 | (TAddress(/192.168.2.3:1000)) reading: false 315 | (TAddress(/192.168.2.3:1000)) AR_Write_Response 316 | (TAddress(/192.168.2.4:1000)) PL_Deliver VALUE form TAddress(/192.168.2.4:1000) with acks: 0 and reading: false 317 | (TAddress(/192.168.2.3:1000)) PL_Deliver ACK from TAddress(/192.168.2.4:1000) with acks: 0 and reading: false 318 | (TAddress(/192.168.2.3:1000)) acks: 1 319 | (TAddress(/192.168.2.3:1000)) reading: false 320 | (TAddress(/192.168.2.4:1000)) PL_Deliver VALUE form TAddress(/192.168.2.2:1000) with acks: 0 and reading: false 321 | (TAddress(/192.168.2.3:1000)) PL_Deliver ACK from TAddress(/192.168.2.2:1000) with acks: 1 and reading: false 322 | (TAddress(/192.168.2.3:1000)) acks: 2 323 | (TAddress(/192.168.2.3:1000)) reading: false 324 | (TAddress(/192.168.2.4:1000)) PL_Deliver VALUE form TAddress(/192.168.2.7:1000) with acks: 0 and reading: false 325 | (TAddress(/192.168.2.3:1000)) PL_Deliver ACK from TAddress(/192.168.2.7:1000) with acks: 2 and reading: false 326 | (TAddress(/192.168.2.3:1000)) acks: 3 327 | (TAddress(/192.168.2.3:1000)) reading: false 328 | (TAddress(/192.168.2.8:1000)) PL_Deliver VALUE form TAddress(/192.168.2.3:1000) with acks: 0 and reading: true 329 | (TAddress(/192.168.2.7:1000)) PL_Deliver ACK from TAddress(/192.168.2.3:1000) with acks: 0 and reading: true 330 | (TAddress(/192.168.2.7:1000)) acks: 1 331 | (TAddress(/192.168.2.7:1000)) reading: true 332 | (TAddress(/192.168.2.8:1000)) PL_Deliver VALUE form TAddress(/192.168.2.1:1000) with acks: 0 and reading: true 333 | (TAddress(/192.168.2.7:1000)) PL_Deliver ACK from TAddress(/192.168.2.1:1000) with acks: 1 and reading: true 334 | (TAddress(/192.168.2.7:1000)) acks: 2 335 | (TAddress(/192.168.2.7:1000)) reading: true 336 | (TAddress(/192.168.2.8:1000)) PL_Deliver VALUE form TAddress(/192.168.2.8:1000) with acks: 0 and reading: true 337 | (TAddress(/192.168.2.7:1000)) PL_Deliver ACK from TAddress(/192.168.2.8:1000) with acks: 2 and reading: true 338 | (TAddress(/192.168.2.7:1000)) acks: 3 339 | (TAddress(/192.168.2.7:1000)) reading: true 340 | (TAddress(/192.168.2.8:1000)) PL_Deliver VALUE form TAddress(/192.168.2.5:1000) with acks: 0 and reading: true 341 | (TAddress(/192.168.2.7:1000)) PL_Deliver ACK from TAddress(/192.168.2.5:1000) with acks: 3 and reading: true 342 | (TAddress(/192.168.2.7:1000)) acks: 4 343 | (TAddress(/192.168.2.7:1000)) reading: true 344 | (TAddress(/192.168.2.8:1000)) PL_Deliver VALUE form TAddress(/192.168.2.6:1000) with acks: 0 and reading: true 345 | HashMap((2,3,Some(-988758023)), (2,3,Some(-988758023)), (2,3,Some(-988758023)), (2,3,Some(-988758023)), (2,3,Some(-988758023))) 346 | 2 3 Some(-988758023) 347 | (TAddress(/192.168.2.8:1000)) BEB_Broadcast WRITE -> 1, 2, 3, Some(-988758023) 348 | (TAddress(/192.168.2.7:1000)) PL_Deliver ACK from TAddress(/192.168.2.6:1000) with acks: 4 and reading: true 349 | (TAddress(/192.168.2.7:1000)) acks: 5 350 | (TAddress(/192.168.2.7:1000)) reading: true 351 | (TAddress(/192.168.2.7:1000)) AR_Read_Response -> Some(-1038318701) 352 | (TAddress(/192.168.2.8:1000)) PL_Deliver VALUE form TAddress(/192.168.2.4:1000) with acks: 0 and reading: true 353 | (TAddress(/192.168.2.7:1000)) PL_Deliver ACK from TAddress(/192.168.2.4:1000) with acks: 0 and reading: false 354 | (TAddress(/192.168.2.7:1000)) acks: 1 355 | (TAddress(/192.168.2.7:1000)) reading: false 356 | (TAddress(/192.168.2.8:1000)) PL_Deliver VALUE form TAddress(/192.168.2.2:1000) with acks: 0 and reading: true 357 | (TAddress(/192.168.2.7:1000)) PL_Deliver ACK from TAddress(/192.168.2.2:1000) with acks: 1 and reading: false 358 | (TAddress(/192.168.2.7:1000)) acks: 2 359 | (TAddress(/192.168.2.7:1000)) reading: false 360 | (TAddress(/192.168.2.8:1000)) PL_Deliver VALUE form TAddress(/192.168.2.7:1000) with acks: 0 and reading: true 361 | (TAddress(/192.168.2.7:1000)) PL_Deliver ACK from TAddress(/192.168.2.7:1000) with acks: 2 and reading: false 362 | (TAddress(/192.168.2.7:1000)) acks: 3 363 | (TAddress(/192.168.2.7:1000)) reading: false 364 | (TAddress(/192.168.2.3:1000)) Sendind ACK form TAddress(/192.168.2.4:1000) -> rid: 1 365 | (TAddress(/192.168.2.1:1000)) Sendind ACK form TAddress(/192.168.2.4:1000) -> rid: 1 366 | (TAddress(/192.168.2.8:1000)) Sendind ACK form TAddress(/192.168.2.4:1000) -> rid: 1 367 | (TAddress(/192.168.2.5:1000)) Sendind ACK form TAddress(/192.168.2.4:1000) -> rid: 1 368 | (TAddress(/192.168.2.6:1000)) Sendind ACK form TAddress(/192.168.2.4:1000) -> rid: 1 369 | (TAddress(/192.168.2.4:1000)) Sendind ACK form TAddress(/192.168.2.4:1000) -> rid: 1 370 | (TAddress(/192.168.2.2:1000)) Sendind ACK form TAddress(/192.168.2.4:1000) -> rid: 1 371 | (TAddress(/192.168.2.7:1000)) Sendind ACK form TAddress(/192.168.2.4:1000) -> rid: 1 372 | (TAddress(/192.168.2.3:1000)) Sendind ACK form TAddress(/192.168.2.8:1000) -> rid: 1 373 | (TAddress(/192.168.2.1:1000)) Sendind ACK form TAddress(/192.168.2.8:1000) -> rid: 1 374 | (TAddress(/192.168.2.8:1000)) Sendind ACK form TAddress(/192.168.2.8:1000) -> rid: 1 375 | (TAddress(/192.168.2.5:1000)) Sendind ACK form TAddress(/192.168.2.8:1000) -> rid: 1 376 | (TAddress(/192.168.2.6:1000)) Sendind ACK form TAddress(/192.168.2.8:1000) -> rid: 1 377 | (TAddress(/192.168.2.4:1000)) Sendind ACK form TAddress(/192.168.2.8:1000) -> rid: 1 378 | (TAddress(/192.168.2.2:1000)) Sendind ACK form TAddress(/192.168.2.8:1000) -> rid: 1 379 | (TAddress(/192.168.2.7:1000)) Sendind ACK form TAddress(/192.168.2.8:1000) -> rid: 1 380 | (TAddress(/192.168.2.4:1000)) PL_Deliver ACK from TAddress(/192.168.2.3:1000) with acks: 0 and reading: false 381 | (TAddress(/192.168.2.4:1000)) acks: 1 382 | (TAddress(/192.168.2.4:1000)) reading: false 383 | (TAddress(/192.168.2.4:1000)) PL_Deliver ACK from TAddress(/192.168.2.1:1000) with acks: 1 and reading: false 384 | (TAddress(/192.168.2.4:1000)) acks: 2 385 | (TAddress(/192.168.2.4:1000)) reading: false 386 | (TAddress(/192.168.2.4:1000)) PL_Deliver ACK from TAddress(/192.168.2.8:1000) with acks: 2 and reading: false 387 | (TAddress(/192.168.2.4:1000)) acks: 3 388 | (TAddress(/192.168.2.4:1000)) reading: false 389 | (TAddress(/192.168.2.4:1000)) PL_Deliver ACK from TAddress(/192.168.2.5:1000) with acks: 3 and reading: false 390 | (TAddress(/192.168.2.4:1000)) acks: 4 391 | (TAddress(/192.168.2.4:1000)) reading: false 392 | (TAddress(/192.168.2.4:1000)) PL_Deliver ACK from TAddress(/192.168.2.6:1000) with acks: 4 and reading: false 393 | (TAddress(/192.168.2.4:1000)) acks: 5 394 | (TAddress(/192.168.2.4:1000)) reading: false 395 | (TAddress(/192.168.2.4:1000)) AR_Write_Response 396 | (TAddress(/192.168.2.4:1000)) PL_Deliver ACK from TAddress(/192.168.2.4:1000) with acks: 0 and reading: false 397 | (TAddress(/192.168.2.4:1000)) acks: 1 398 | (TAddress(/192.168.2.4:1000)) reading: false 399 | (TAddress(/192.168.2.4:1000)) PL_Deliver ACK from TAddress(/192.168.2.2:1000) with acks: 1 and reading: false 400 | (TAddress(/192.168.2.4:1000)) acks: 2 401 | (TAddress(/192.168.2.4:1000)) reading: false 402 | (TAddress(/192.168.2.4:1000)) PL_Deliver ACK from TAddress(/192.168.2.7:1000) with acks: 2 and reading: false 403 | (TAddress(/192.168.2.4:1000)) acks: 3 404 | (TAddress(/192.168.2.4:1000)) reading: false 405 | (TAddress(/192.168.2.8:1000)) PL_Deliver ACK from TAddress(/192.168.2.3:1000) with acks: 0 and reading: true 406 | (TAddress(/192.168.2.8:1000)) acks: 1 407 | (TAddress(/192.168.2.8:1000)) reading: true 408 | (TAddress(/192.168.2.8:1000)) PL_Deliver ACK from TAddress(/192.168.2.1:1000) with acks: 1 and reading: true 409 | (TAddress(/192.168.2.8:1000)) acks: 2 410 | (TAddress(/192.168.2.8:1000)) reading: true 411 | (TAddress(/192.168.2.8:1000)) PL_Deliver ACK from TAddress(/192.168.2.8:1000) with acks: 2 and reading: true 412 | (TAddress(/192.168.2.8:1000)) acks: 3 413 | (TAddress(/192.168.2.8:1000)) reading: true 414 | (TAddress(/192.168.2.8:1000)) PL_Deliver ACK from TAddress(/192.168.2.5:1000) with acks: 3 and reading: true 415 | (TAddress(/192.168.2.8:1000)) acks: 4 416 | (TAddress(/192.168.2.8:1000)) reading: true 417 | (TAddress(/192.168.2.8:1000)) PL_Deliver ACK from TAddress(/192.168.2.6:1000) with acks: 4 and reading: true 418 | (TAddress(/192.168.2.8:1000)) acks: 5 419 | (TAddress(/192.168.2.8:1000)) reading: true 420 | (TAddress(/192.168.2.8:1000)) AR_Read_Response -> Some(-988758023) 421 | (TAddress(/192.168.2.8:1000)) PL_Deliver ACK from TAddress(/192.168.2.4:1000) with acks: 0 and reading: false 422 | (TAddress(/192.168.2.8:1000)) acks: 1 423 | (TAddress(/192.168.2.8:1000)) reading: false 424 | (TAddress(/192.168.2.8:1000)) PL_Deliver ACK from TAddress(/192.168.2.2:1000) with acks: 1 and reading: false 425 | (TAddress(/192.168.2.8:1000)) acks: 2 426 | (TAddress(/192.168.2.8:1000)) reading: false 427 | (TAddress(/192.168.2.8:1000)) PL_Deliver ACK from TAddress(/192.168.2.7:1000) with acks: 2 and reading: false 428 | (TAddress(/192.168.2.8:1000)) acks: 3 429 | (TAddress(/192.168.2.8:1000)) reading: false -------------------------------------------------------------------------------- /Exercise SharedMemory/Exercise-SharedMemory.md: -------------------------------------------------------------------------------- 1 | ### Assignment 3: Implementing an Atomic N-N register ### 2 | In this programming assignment you will have to complete the implementation of an atomic register that supports multiple writers and readers. 3 | 4 | When you are done you simply have to export your notebook and then upload it in the “Programming Exercise 3” page. 5 | 6 | __Things to Remember__: 7 | 1. Basic components such as PerfectLink, Network and Timer are already provided. No need to implement them. 8 | 2. Execute the imports defined below before compiling your component implementations. 9 | 3. We recommend making use of the component state and internal messages we have provided, if any, to complete the implementation logic. 10 | 4. You can always print messages to the output log, from within handlers to see what happens during the simulation. e.g. println(s"Process $self delivers message $msg"); 11 | 5. Remember that during the simulation check you can print and observe the simulation time, i.e. with System.currentTimeMillis(). 12 | 5. Do not forget to run the checker code block after each component implementation to ensure that all properties are satisfied before exporting and submitting the notebook. 13 | 6. You can always restart the Kompics Interpreter to start fresh (Interpreter→KompicsInterpreter→Click Restart) 14 | 15 | Good luck! :) 16 | 17 | ## The N-N Atomic Register ## 18 | 19 | A (single) Atomic Register Abstraction (AR), in Kompics terms, is a component that **provides** the following port *(already imported in the notebook)*. 20 | ```scala 21 | class AtomicRegister extends Port { 22 | request[AR_Read_Request] 23 | request[AR_Write_Request] 24 | indication[AR_Read_Response] 25 | indication[AR_Write_Response] 26 | } 27 | ``` 28 | 29 | An **AR** component should request reads (`AR_Read_Request`) or writes (`AR_Write_Request`) and respond with `AR_Read_Response` or `AR_Write_Response` events respectively as defined below: 30 | ```scala 31 | case class AR_Read_Request() extends KompicsEvent 32 | case class AR_Read_Response(value: Option[Any]) extends KompicsEvent 33 | case class AR_Write_Request(value: Any) extends KompicsEvent 34 | case class AR_Write_Response() extends KompicsEvent 35 | ``` 36 | 37 | As you have already learnt from the course lectures, Atomic Registers should be linerarizable and also terminate which we summarize with the following properties: 38 | 39 | 1. **Termination**: *If a correct process invokes an operation, then the operation eventually completes.* 40 | 2. **Atomicity**: *Every read operation returns the value that was written most recently in a hypothetical execution, where every failed operation appears to be complete or does not appear to have been invoked at all, and every complete operation appears to have been executed at some instant between its invocation and its completion.* -------------------------------------------------------------------------------- /Exercise SharedMemory/Exercise-SharedMemory.scala: -------------------------------------------------------------------------------- 1 | //Rremember to execute the following imports first 2 | import se.kth.edx.id2203.core.ExercisePrimitives._ 3 | import se.kth.edx.id2203.core.Ports._ 4 | import se.kth.edx.id2203.validation._ 5 | import se.sics.kompics.network._ 6 | import se.sics.kompics.sl.{Init, _} 7 | import se.sics.kompics.{ComponentDefinition => _, Port => _,KompicsEvent} 8 | 9 | import scala.collection.mutable.Map 10 | import scala.language.implicitConversions 11 | 12 | 13 | //The following events are to be used internally by the Atomic Register implementation below 14 | case class READ(rid: Int) extends KompicsEvent; 15 | case class VALUE(rid: Int, ts: Int, wr: Int, value: Option[Any]) extends KompicsEvent; 16 | case class WRITE(rid: Int, ts: Int, wr: Int, writeVal: Option[Any]) extends KompicsEvent; 17 | case class ACK(rid: Int) extends KompicsEvent; 18 | 19 | /** 20 | * This augments tuples with comparison operators implicitly, which you can use in your code. 21 | * examples: (1,2) > (1,4) yields 'false' and (5,4) <= (7,4) yields 'true' 22 | */ 23 | implicit def addComparators[A](x: A)(implicit o: math.Ordering[A]): o.Ops = o.mkOrderingOps(x); 24 | 25 | //HINT: After you execute the latter implicit ordering you can compare tuples as such within your component implementation: 26 | (1,2) <= (1,4); 27 | 28 | 29 | 30 | 31 | class ReadImposeWriteConsultMajority(init: Init[ReadImposeWriteConsultMajority]) extends ComponentDefinition { 32 | 33 | //subscriptions 34 | 35 | val nnar = provides[AtomicRegister]; 36 | 37 | val pLink = requires[PerfectLink]; 38 | val beb = requires[BestEffortBroadcast]; 39 | 40 | //state and initialization 41 | 42 | val (self: Address, n: Int, selfRank: Int) = init match { 43 | case Init(selfAddr: Address, n: Int) => (selfAddr, n, AddressUtils.toRank(selfAddr)) 44 | }; 45 | 46 | var (ts, wr) = (0, 0); 47 | var value: Option[Any] = None; 48 | var acks = 0; 49 | var readval: Option[Any] = None; 50 | var writeval: Option[Any] = None; 51 | var rid = 0; 52 | var readlist: Map[Address, (Int, Int, Option[Any])] = Map.empty 53 | var reading = false; 54 | 55 | //handlers 56 | 57 | nnar uponEvent { 58 | case AR_Read_Request() => handle { 59 | rid = rid + 1; 60 | acks = 0; 61 | readlist = Map.empty; 62 | reading = true; 63 | println(s"($self) READ: BEB_Broadcasting -> rid: $rid reading: $reading"); 64 | trigger(BEB_Broadcast(READ(rid)) -> beb); 65 | }; 66 | case AR_Write_Request(wval) => handle { 67 | rid = rid + 1; 68 | /*writeval = wval;*/ 69 | writeval = Some(wval); 70 | acks = 0; 71 | readlist = Map.empty; 72 | trigger(BEB_Broadcast(READ(rid)) -> beb); 73 | println(s"($self) WRITE: BEB_Broadcasting -> rid: $rid"); 74 | } 75 | } 76 | 77 | beb uponEvent { 78 | case BEB_Deliver(src, READ(readID)) => handle { 79 | trigger(PL_Send(src, VALUE(readID, ts, wr, value)) -> pLink); 80 | println(s"($self) Sendind VALUE form $src -> rid: $readID timestamp: $ts wr: $wr value: $value"); 81 | } 82 | case BEB_Deliver(src, w: WRITE) => handle { 83 | if ((ts, wr)<(w.ts, w.wr)){ 84 | /*(ts, wr, value) = (w.ts, w.wr, w.writeVal)*/ 85 | ts = w.ts; 86 | wr = w.wr; 87 | value = w.writeVal; 88 | } 89 | trigger(PL_Send(src, ACK(w.rid)) -> pLink); 90 | println(s"($self) Sendind ACK form $src -> rid: $rid"); 91 | } 92 | } 93 | 94 | pLink uponEvent { 95 | case PL_Deliver(src, v: VALUE) => handle { 96 | println(s"($self) PL_Deliver VALUE form $src with acks: $acks and reading: $reading"); 97 | if (v.rid == rid) { 98 | /*val myVal: Option[Any] = v.value;*/ 99 | readlist.update(src,(v.ts, v.wr, v.value)); 100 | if(readlist.size > n/2){ 101 | println(readlist.values); 102 | var maxts = readlist.maxBy(maplist => (maplist._2._1, maplist._2._2))._2._1; 103 | var rr= readlist.maxBy(maplist => (maplist._2._1, maplist._2._2))._2._2; 104 | readval = readlist.maxBy(maplist => (maplist._2._1, maplist._2._2))._2._3; 105 | println(s"$maxts $rr $readval"); 106 | readlist = Map.empty; 107 | var bcastval: Option[Any] = None; 108 | if(reading){ 109 | bcastval = readval; 110 | } else { 111 | rr = selfRank; 112 | maxts = maxts + 1; 113 | bcastval = writeval; 114 | } 115 | trigger(BEB_Broadcast(WRITE(rid, maxts, rr, bcastval)) -> beb); 116 | println(s"($self) BEB_Broadcast WRITE -> $rid, $maxts, $rr, $bcastval"); 117 | } 118 | } 119 | } 120 | case PL_Deliver(src, v: ACK) => handle { 121 | println(s"($self) PL_Deliver ACK from $src with acks: $acks and reading: $reading"); 122 | if (v.rid == rid) { 123 | acks = acks + 1; 124 | println(s"($self) acks: $acks"); 125 | println(s"($self) reading: $reading"); 126 | if(acks > n/2){ 127 | acks = 0; 128 | if (reading){ 129 | reading = false; 130 | trigger(AR_Read_Response(readval) -> nnar); 131 | println(s"($self) AR_Read_Response -> $readval"); 132 | } else { 133 | trigger(AR_Write_Response() -> nnar); 134 | println(s"($self) AR_Write_Response"); 135 | } 136 | } 137 | } 138 | } 139 | } 140 | } -------------------------------------------------------------------------------- /Game of Life/Game of Life.json: -------------------------------------------------------------------------------- 1 | {"paragraphs":[{"text":"%md\n# Conway's Game of Life\nThe purpose of this task is to run a version of [Conway's Game of Life](https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life) using Kompics component for each cell.\n\nAll the Kompics relevant code is already implemented for you, however, and you only need to fill in the following 4 rules:\n1. Any live cell with fewer than two live neighbours dies, as if caused by under-population.\n2. Any live cell with two or three live neighbours lives on to the next generation.\n3. Any live cell with more than three live neighbours dies, as if by over-population.\n4. Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.\n \nImplement these rules at the marked position in the code below.\n\nNote that while this is a graded assignment, there are no tests and the assignment always passes automatically.\nThe purpose is merely for you to experiment with the zeppelin environment and familiarise yourself with the assignment submission procedure.\n\nOnce you have the basic version working, feel free to experiment with different initial state generators, and numbers of generations.\n\n\n","user":"anonymous","dateUpdated":"2017-11-27T00:02:51+0000","config":{"editorSetting":{"language":"markdown","editOnDblClick":true},"colWidth":12,"editorMode":"ace/mode/markdown","editorHide":true,"fontSize":9,"results":[{"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}}],"enabled":true,"tableHide":false},"settings":{"params":{},"forms":{}},"results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"
\n

Conway’s Game of Life

\n

The purpose of this task is to run a version of Conway’s Game of Life using Kompics component for each cell.

\n

All the Kompics relevant code is already implemented for you, however, and you only need to fill in the following 4 rules:
1. Any live cell with fewer than two live neighbours dies, as if caused by under-population.
2. Any live cell with two or three live neighbours lives on to the next generation.
3. Any live cell with more than three live neighbours dies, as if by over-population.
4. Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.

\n

Implement these rules at the marked position in the code below.

\n

Note that while this is a graded assignment, there are no tests and the assignment always passes automatically.
The purpose is merely for you to experiment with the zeppelin environment and familiarise yourself with the assignment submission procedure.

\n

Once you have the basic version working, feel free to experiment with different initial state generators, and numbers of generations.

\n
"}]},"apps":[],"jobName":"paragraph_1511740879908_68087522","id":"20160902-193003_1338549382","dateCreated":"2017-11-27T00:01:19+0000","dateStarted":"2017-11-27T00:02:51+0000","dateFinished":"2017-11-27T00:02:51+0000","status":"FINISHED","progressUpdateIntervalMs":500,"focus":true,"$$hashKey":"object:208"},{"text":"import se.kth.edx.id2203.tutorial.gameoflife._\nimport se.kth.edx.id2203.validation._\nimport se.kth.edx.id2203.core._\nimport java.util.Random;\nimport se.sics.kompics.sl._\nimport se.sics.kompics.{ Kompics }\n\ncase class CellCInit(x: Int, y: Int, init: State.Initializer) extends se.sics.kompics.Init[Cell]\n\nclass CellC(init: CellCInit) extends Cell { // class Cell is a KompicsComponent\n // this cell's location in the grid\n val xPos = init.x;\n val yPos = init.y;\n // get the initial state from the State.Initializer (see below this class)\n private var state: State = init.init.apply(xPos, yPos);\n // initialize our view of our neighbours\n private val view = scala.collection.mutable.Map.empty[Tuple2[Int, Int], State];\n // keep track of the generation we are currently communicating on to not mix up delayed messages\n private var lastGen = -1l;\n\n // declare our ports (the same one but in both directions for broadcasting to neighbours and receiving their broadcasts)\n val envIn = requires(EnvironmentPort);\n val envOut = provides(EnvironmentPort);\n // handle messages on incoming environment port\n envIn uponEvent {\n case Progress(generation) => handle {\n //println(s\"Cell($xPos, $yPos) starting generation $generation as $state\"); // uncomment if you want to see some printouts\n // for every generaton broadcast our current state\n trigger(BroadcastState(generation, xPos, yPos, state) -> envOut);\n // and prepare to receiver other's states\n if (lastGen < generation) {\n view.clear();\n lastGen = generation;\n }\n }\n case BroadcastState(generation, x, y, otherState) => handle {\n // same as above, just in case we get another component's state broadcast before the instruction to move to the next generation\n if (lastGen < generation) {\n view.clear();\n lastGen = generation;\n }\n // add the received state to our view\n view += ((x -> y) -> otherState);\n //println(s\"Cell($xPos, $yPos) got state $otherState from Cell($x, $y) leading to: $view\"); // uncomment if you want to see some printouts\n if (view.size == 8) { // once we get the last state broadcast in a generation (from everyone around us: 3x3-1)\n // count live cells in our neighbourhood\n val liveC = view.values.count {\n case Alive => true\n case _ => false\n };\n // apply game of life rules to decide our next state based on current state and live count\n // **********************************\n // ******* STUDENT CODE HERE ********\n // **********************************\n if (state == Alive && liveC < 2) {\n state = Dead\n }\n else if (state == Alive && liveC > 3) {\n state = Dead\n }\n else if (state == Alive && ( liveC == 2 || liveC == 3 )) {\n state = Alive\n }\n else if (state == Dead && liveC == 3) {\n state = Alive\n }\n }\n }\n }\n}\n\n\nval rand = new Random(System.currentTimeMillis());\n// randomly generate the initial state (easy but boring...try to do something more interesting if you like)\nval defaultInit: State.Initializer = (x: Int, y: Int) => {\n if (rand.nextBoolean()) {\n Alive\n } else {\n Dead\n }\n}\n// just a way to generate a child init object from a method\nval toCellCInit: Cell.Initializer = {\n case (x: Int, y: Int, init: State.Initializer) => CellCInit(x, y, init).asInstanceOf[se.sics.kompics.Init[Cell]]\n};\n\nval cellclass = classOf[CellC].asInstanceOf[Class[Cell]] // nvm some ugly type magic...Java Kompics is sometimes a bit overspecific on what types it wants\nrunKompics[ParentC](GameOfLifeInit(defaultInit, cellclass, toCellCInit, numGenerations = 10)); // create the Kompics environment and wait for it to finish\n\ncheckExample[ParentC] // generate grading token\n \n ","user":"anonymous","dateUpdated":"2017-12-14T16:09:19+0000","config":{"lineNumbers":true,"editorSetting":{"language":"scala","editOnDblClick":false},"editorMode":"ace/mode/scala","colWidth":12,"fontSize":9,"results":{},"enabled":true,"graph":{"mode":"table","height":300,"optionOpen":false,"keys":[],"values":[],"groups":[],"scatter":{}}},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1511740879911_68472271","id":"20160615-191351_1691822922","dateCreated":"2017-11-27T00:01:19+0000","dateStarted":"2017-12-14T16:09:19+0000","dateFinished":"2017-12-14T16:09:20+0000","status":"FINISHED","progressUpdateIntervalMs":500,"$$hashKey":"object:209","results":{"code":"SUCCESS","msg":[{"type":"HTML","data":"Starting generation 0...
Completed generation 0
Starting generation 1
Completed generation 1
Starting generation 2
Completed generation 2
Starting generation 3
Completed generation 3
Starting generation 4
Completed generation 4
Starting generation 5
Completed generation 5
Starting generation 6
Completed generation 6
Starting generation 7
Completed generation 7
Starting generation 8
Completed generation 8
Starting generation 9
Completed generation 9
Starting generation 10
Completed generation 10
Finishing up.

To see the generated output click here



Your submission has been locally simulated and validated.

Click Here to view the output of the simulation.


Correction Results
PASSED Example Run ✔: You have run the example successfully!

Final Comments
**************
Congratulations! Your implementation of the 'Game of Life' satisfies all properties!
A unique token has been generated for your submission right below. Please do not edit.

{\"gradingToken\":[45,45,45,45,45,66,69,71,73,78,32,80,71,80,32,77,69,83,83,65,71,69,45,45,45,45,45,10,86,101,114,115,105,111,110,58,32,66,67,80,71,32,118,49,46,53,53,10,10,104,81,73,77,65,57,79,116,77,118,84,69,98,74,49,102,65,81,47,47,87,50,100,104,116,111,101,55,68,76,120,83,74,74,48,72,103,75,119,102,88,88,116,120,105,75,48,104,118,117,67,113,99,112,122,70,120,70,56,82,102,80,102,80,10,102,119,53,120,72,112,65,67,111,106,118,57,116,56,122,108,119,101,111,74,85,101,103,104,78,105,85,43,69,68,52,88,108,79,70,101,57,116,80,115,111,51,72,66,121,73,106,101,109,115,69,104,112,72,56,99,77,113,49,89,102,86,88,65,10,51,104,54,86,43,88,109,84,69,108,121,90,115,118,79,103,111,105,82,113,70,57,110,79,65,87,110,104,66,88,89,66,105,99,112,82,66,115,80,121,106,71,73,86,109,109,66,70,109,112,55,118,69,66,114,117,70,109,90,103,99,68,43,80,10,122,101,99,90,121,57,121,97,87,109,82,70,108,111,52,68,86,71,70,105,66,78,84,90,109,79,69,115,71,118,111,78,90,97,43,115,105,83,105,100,98,121,71,108,82,104,66,49,119,107,66,71,114,121,121,71,97,119,104,97,74,48,49,111,10,120,68,54,49,76,116,50,52,107,90,87,80,53,79,50,74,99,89,101,98,100,122,43,81,90,84,99,55,112,112,104,54,102,57,80,79,70,53,76,49,75,120,111,114,51,77,79,89,47,43,85,69,114,71,100,102,120,86,71,56,75,101,85,115,10,120,97,117,82,98,68,119,72,76,71,86,82,90,113,119,118,99,57,80,47,52,111,80,121,100,52,49,70,68,73,75,112,69,119,55,49,84,89,113,49,116,79,99,106,84,105,51,71,53,73,117,88,120,112,75,81,89,53,54,74,71,86,98,76,10,105,80,117,57,102,117,99,102,85,121,66,90,86,112,111,70,103,56,50,97,47,118,79,118,79,84,54,89,66,72,73,116,70,106,73,47,81,57,73,53,122,112,74,70,77,116,105,122,103,82,106,119,79,69,78,65,57,50,122,116,118,56,69,110,10,102,73,104,47,118,122,57,108,101,50,71,98,80,109,104,114,81,68,119,106,83,107,81,69,50,65,57,89,99,56,117,119,101,87,43,101,90,78,112,54,55,115,80,121,57,73,47,120,114,65,65,74,43,120,107,86,82,72,70,86,114,102,69,120,10,99,87,120,103,90,50,48,72,99,104,97,90,80,80,84,100,73,115,57,68,105,55,55,122,88,70,81,120,56,52,77,88,108,97,81,104,53,53,81,106,103,80,109,55,53,82,108,81,104,69,54,102,79,67,113,65,84,114,112,49,50,79,118,53,10,79,103,107,49,122,115,54,77,85,109,98,118,48,111,109,112,105,119,114,74,85,78,67,122,67,82,112,102,71,120,104,119,108,82,114,78,97,99,115,105,114,56,101,83,71,118,113,112,111,73,119,69,99,57,109,53,77,65,121,54,87,55,72,121,10,84,67,43,110,53,51,112,106,89,109,77,121,73,77,55,57,122,65,51,51,114,111,99,115,80,112,69,115,88,113,74,57,101,68,115,49,121,114,110,116,120,51,54,105,107,75,82,99,89,101,97,119,75,101,89,70,81,77,105,51,67,77,122,83,10,108,103,72,99,85,85,118,56,78,47,101,115,71,76,74,110,108,108,70,105,102,69,115,83,108,100,75,104,74,110,70,81,66,73,73,48,72,89,100,106,105,117,105,71,112,98,115,98,57,52,43,67,47,111,120,105,104,104,117,76,112,112,82,84,10,55,56,108,49,82,53,71,110,54,85,114,56,78,121,112,84,110,87,50,101,107,118,76,50,99,107,74,55,102,122,81,53,108,97,83,54,54,101,57,117,115,74,82,47,84,54,66,120,80,106,84,98,65,83,114,72,99,78,89,55,51,86,109,80,10,75,116,107,102,56,101,87,86,53,85,80,98,49,97,82,106,84,76,43,108,121,104,76,111,120,101,104,107,103,106,73,43,66,87,85,112,73,112,117,109,56,105,97,104,101,49,77,77,85,54,47,54,71,70,113,75,104,52,114,104,90,102,68,69,10,65,88,47,52,88,101,77,114,102,65,61,61,10,61,113,100,80,75,10,45,45,45,45,45,69,78,68,32,80,71,80,32,77,69,83,83,65,71,69,45,45,45,45,45,10]}
import se.kth.edx.id2203.tutorial.gameoflife._
import se.kth.edx.id2203.validation._
import se.kth.edx.id2203.core._
import java.util.Random
import se.sics.kompics.sl._
import se.sics.kompics.Kompics
defined class CellCInit
defined class CellC
rand: java.util.Random = java.util.Random@22d1da41
defaultInit: se.kth.edx.id2203.tutorial.gameoflife.State.Initializer =
toCellCInit: se.kth.edx.id2203.tutorial.gameoflife.Cell.Initializer =
cellclass: Class[se.kth.edx.id2203.tutorial.gameoflife.Cell] = class CellC
res20: Boolean = true
"}]}},{"user":"anonymous","dateUpdated":"2017-11-27T00:02:31+0000","config":{"editorSetting":{"language":"scala","editOnDblClick":false},"colWidth":12,"editorMode":"ace/mode/scala","fontSize":9,"results":{},"enabled":true},"settings":{"params":{},"forms":{}},"apps":[],"jobName":"paragraph_1511740879912_66548526","id":"20171016-121142_1198453026","dateCreated":"2017-11-27T00:01:19+0000","status":"FINISHED","errorMessage":"","progressUpdateIntervalMs":500,"$$hashKey":"object:210"}],"name":"Example - Game of Life","id":"2CZMCFK6U","angularObjects":{"2BKQCVH92:shared_process":[],"2CVXXPNWV:shared_process":[]},"config":{"looknfeel":"default","personalizedMode":"false"},"info":{}} -------------------------------------------------------------------------------- /Game of Life/Game of Life.scala: -------------------------------------------------------------------------------- 1 | import se.kth.edx.id2203.tutorial.gameoflife._ 2 | import se.kth.edx.id2203.validation._ 3 | import se.kth.edx.id2203.core._ 4 | import java.util.Random; 5 | import se.sics.kompics.sl._ 6 | import se.sics.kompics.{ Kompics } 7 | 8 | case class CellCInit(x: Int, y: Int, init: State.Initializer) extends se.sics.kompics.Init[Cell] 9 | 10 | class CellC(init: CellCInit) extends Cell { // class Cell is a KompicsComponent 11 | // this cell's location in the grid 12 | val xPos = init.x; 13 | val yPos = init.y; 14 | // get the initial state from the State.Initializer (see below this class) 15 | private var state: State = init.init.apply(xPos, yPos); 16 | // initialize our view of our neighbours 17 | private val view = scala.collection.mutable.Map.empty[Tuple2[Int, Int], State]; 18 | // keep track of the generation we are currently communicating on to not mix up delayed messages 19 | private var lastGen = -1l; 20 | 21 | // declare our ports (the same one but in both directions for broadcasting to neighbours and receiving their broadcasts) 22 | val envIn = requires(EnvironmentPort); 23 | val envOut = provides(EnvironmentPort); 24 | // handle messages on incoming environment port 25 | envIn uponEvent { 26 | case Progress(generation) => handle { 27 | //println(s"Cell($xPos, $yPos) starting generation $generation as $state"); // uncomment if you want to see some printouts 28 | // for every generaton broadcast our current state 29 | trigger(BroadcastState(generation, xPos, yPos, state) -> envOut); 30 | // and prepare to receiver other's states 31 | if (lastGen < generation) { 32 | view.clear(); 33 | lastGen = generation; 34 | } 35 | } 36 | case BroadcastState(generation, x, y, otherState) => handle { 37 | // same as above, just in case we get another component's state broadcast before the instruction to move to the next generation 38 | if (lastGen < generation) { 39 | view.clear(); 40 | lastGen = generation; 41 | } 42 | // add the received state to our view 43 | view += ((x -> y) -> otherState); 44 | //println(s"Cell($xPos, $yPos) got state $otherState from Cell($x, $y) leading to: $view"); // uncomment if you want to see some printouts 45 | if (view.size == 8) { // once we get the last state broadcast in a generation (from everyone around us: 3x3-1) 46 | // count live cells in our neighbourhood 47 | val liveC = view.values.count { 48 | case Alive => true 49 | case _ => false 50 | }; 51 | // apply game of life rules to decide our next state based on current state and live count 52 | // ********************************** 53 | // ******* STUDENT CODE HERE ******** 54 | // ********************************** 55 | if (state == Alive && liveC < 2) { 56 | state = Dead 57 | } 58 | else if (state == Alive && liveC > 3) { 59 | state = Dead 60 | } 61 | else if (state == Alive && ( liveC == 2 || liveC == 3 )) { 62 | state = Alive 63 | } 64 | else if (state == Dead && liveC == 3) { 65 | state = Alive 66 | } 67 | } 68 | } 69 | } 70 | } 71 | 72 | 73 | val rand = new Random(System.currentTimeMillis()); 74 | // randomly generate the initial state (easy but boring...try to do something more interesting if you like) 75 | val defaultInit: State.Initializer = (x: Int, y: Int) => { 76 | if (rand.nextBoolean()) { 77 | Alive 78 | } else { 79 | Dead 80 | } 81 | } 82 | // just a way to generate a child init object from a method 83 | val toCellCInit: Cell.Initializer = { 84 | case (x: Int, y: Int, init: State.Initializer) => CellCInit(x, y, init).asInstanceOf[se.sics.kompics.Init[Cell]] 85 | }; 86 | 87 | val cellclass = classOf[CellC].asInstanceOf[Class[Cell]] // nvm some ugly type magic...Java Kompics is sometimes a bit overspecific on what types it wants 88 | runKompics[ParentC](GameOfLifeInit(defaultInit, cellclass, toCellCInit, numGenerations = 10)); // create the Kompics environment and wait for it to finish 89 | 90 | checkExample[ParentC] // generate grading token 91 | 92 | -------------------------------------------------------------------------------- /Game of Life/Game of life.md: -------------------------------------------------------------------------------- 1 | # Conway's Game of Life 2 | The purpose of this task is to run a version of [Conway's Game of Life](https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life) using Kompics component for each cell. 3 | 4 | All the Kompics relevant code is already implemented for you, however, and you only need to fill in the following 4 rules: 5 | 1. Any live cell with fewer than two live neighbours dies, as if caused by under-population. 6 | 2. Any live cell with two or three live neighbours lives on to the next generation. 7 | 3. Any live cell with more than three live neighbours dies, as if by over-population. 8 | 4. Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction. 9 | 10 | Implement these rules at the marked position in the code below. 11 | 12 | Note that while this is a graded assignment, there are no tests and the assignment always passes automatically. 13 | The purpose is merely for you to experiment with the zeppelin environment and familiarise yourself with the assignment submission procedure. 14 | 15 | Once you have the basic version working, feel free to experiment with different initial state generators, and numbers of generations. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Reliable-Distributed-Algorithms 2 | 3 | In this repository you can find my assignments regarding the [Reliable Distributed Algorithms - part 1](https://www.edx.org/course/reliable-distributed-algorithms-part-1-kthx-id2203-1x-0) course on Edx. 4 | --------------------------------------------------------------------------------