Om aan de bijzondere verplichting van IB2302 te voldoen, dient de student vijf programmeeropdrachten (in Java) succesvol te voltooien. De opdrachten beslaan de volgende onderwerpen:
- Opdracht 1: Steen-Papier-Schaar (week 1)
- Opdracht 2: Gedragsmodellen (week 2)
- Opdracht 3: Snapshots (week 3-4)
- Opdracht 4: Waves (week 5-6)
- Opdracht 5: Deadlock-detectie (week 7-8)
Bij elke opdracht wordt aan de student verstrekt: (a) klassen, waarin sommige methoden nog niet geïmplementeerd zijn; (b) unit-tests voor de methoden die nog niet geïmplementeerd zijn; (c) een library die de student dient te gebruiken om de methoden die nog niet geïmplementeerd zijn te implementeren. De opdracht is dus: implementeer de methoden die nog niet geïmplementeerd zijn.
Wanneer alle opdrachten zijn gemaakt, kunnen deze collectief worden ingeleverd ter beoordeling, inclusief een bondig reflectieverslag (maximaal 800 woorden). Er zijn twee mogelijke scores: voldoende en onvoldoende. De student haalt een voldoende als aan elk van de volgende eisen wordt voldaan:
- Elke verstrekte unit-test voor elke opdracht slaagt.
- De cyclomatische complexiteit van elke geïmplementeerde methode is kleiner dan het aantal unit-tests voor die methode. De intentie van deze eis is dat de docent "sjoemelimplementaties" (= implementaties die tijdens de executie proberen te achterhalen welke unit-test wordt uitgevoerd en aan de hand daarvan precies de verwachte output produceren) kan afkeuren. Zolang het duidelijk is dat er van een sjoemelimplementatie geen sprake is, hoeft de student zich geen zorgen te maken over wat cyclomatische complexiteit precies inhoudt.
- Het reflectieverslag geeft inzicht in de ervaringen van de student met het programmeren van gedistribueerde algoritmen.
Voor de duidelijkheid: elke unit-test die later bij de beoordeling door de docent wordt gebruikt, is een unit-test die eerder aan de student is verstrekt.
Per inschrijving heeft de student drie inleverpogingen. Als na de derde inleverpoging nog geen voldoende is behaald, dan kan de student het vak niet meer succesvol afronden. Zie Brightspace voor deadlines.
Voor het maken van de programmeeropdrachten bieden we een virtual machine (VM) aan. Het doel van de VM is om alle studenten te laten werken met hetzelfde besturingssysteem, dezelfde versie van Java, en dezelfde versie van Eclipse; dit maakt het oplossen van problemen door de docent, zodra de VM is geinstalleerd is (hieronder beschreven), een stuk eenvoudiger voor zowel de student als de docent. Hoewel sterk aangeraden, is het niet verplicht om de VM te gebruiken. Echter, de docent biedt geen ondersteuning bij installatie en configuratie van de benodigde tools (Java SDK, Eclipse, git) buiten de VM.
- Download en installeer VirtualBox.
- Download de virtual machine.
- Importeer de VM in VirtualBox.
- [Optioneel] Verander de keyboard layout naar
azerty:- Start de VM.
- Open een terminal en voer uit:
setxkbmap be
- Start de VM.
- Open een terminal en voer uit:
git clone https://github.com/sschivo/ib2302.git - Open Eclipse.
- Importeer de geclonede repository:
- Klik:
File(menubalk) >Import...>General>Existing Projects into Workspace - Bij
Select root directory, vul in:/home/ou/ib2302/Opdrachten - Klik:
Finish
- Klik:
De verstrekte code bestaat uit zes packages: week1, week2, week34, week56, week78, en framework. De eerste vijf packages komen overeen met de vijf opdrachten. Package framework is een kleine library waarmee gedistribueerde algoritmen kunnen worden geïmplementeerd. De benodigde klassen en interfaces op een rijtje:
-
Klasse
Processrepresenteert processen. Relevante methoden zijn:p.getName()retourneert de naam vanp.p.getIncoming()retourneert de inkomende kanalen vanp.p.getOutgoing()retourneert de uitgaande kanalen vanp.p.init()laatpzichzelf initialiseren (= verwerking van een init-event)p.send(m,c)laatpberichtmversturen langs kanaalc(als onderdeel van de verwerking van een init- of ontvang-event).p.receive(m,c)laatpberichtmontvangen langs kanaalc(= verwerking van een ontvang-event).p.print(s)laatptekstsprinten naarSystem.out(als onderdeel van de verwerking van een init- of ontvang-event).
NB1:
Processis een abstracte klasse, metinitenreceiveals abstracte methoden. Dit betekent dat er geen instanties vanProcessgecreëerd kunnen worden; van (niet-abstracte) subklassen vanProcess(die methodeninitenreceivevan een implementatie voorzien) kunnen wel instanties worden gecreëerd.NB2: Importeer
Processdoorimport framework.Processhandmatig toe te voegen; Eclipse doet dit niet automatisch (en waarschuwt ook niet als het is vergeten), omdat er in de standaardbibliotheek van Java ook een klasseProcessis (java.lang.Process).NB3: Methode
printslaat intern op wat er tijdens een executie allemaal al geprint is (en doet dus meer danSystem.out.print). Deze informatie wordt in de unit-tests geraadpleegd. Gebruik deze methode dus alleen zoals geinstrueerd in de opdrachtbeschrijvingen; gebruik voor alle andere prints (bijvoorbeeld om te debuggen)System.out.printen/ofSystem.out.println. -
Klasse
Channelrepresenteert kanalen tussen processen. Relevante methoden zijn:c.getSender()retourneert het proces aan de ingang van het kanaalc.c.getReceiver()retourneert het proces aan de uitgang van het kanaalc.
NB: Klasse
Channelis al volledig geimplementeerd; de student hoeft hier zelf niets aan te doen. Het plaatsen van een bericht in een kanaal gebeurt als onderdeel van methodesendvan klasseProcess. -
Interface
Messagerepresenteert berichten. De interface specificeert geen methoden; klassen die de interface implementeren zijn vrij om zelf relevante attributen en methoden aan te bieden. -
Klasse
IllegalReceiveExceptionis een subklasse vanException. Het idee is dat eenIllegalReceiveExceptionwordt geworpen als onderdeel van methodeaanroepp.receive(m,c)als deze aanroep niet is toegestaan volgens het gedistribueerde algoritme datpvolgt (afhankelijk van de lokale toestand vanpen/of de argumenten van de aanroep). -
Kennis van de overige klassen in package
frameworkis niet nodig voor het maken van de opdrachten.
-
Met uitzondering van Opdracht 2 bestaat elke opdracht uit het schrijven van implementaties van methoden
initenreceive(= implementeren van gedrag dat een proces moet vertonen wanneer init- en ontvang-events plaatsvinden), in subklassen van klasseframework.Process. Gebruik hiervoor als basis de informele beschrijvingen die besproken zijn in de hoorcolleges. -
Het staat de student vrij om—geheel naar eigen inzicht—extra attributen, methoden, en zelfs klassen toe te voegen. Echter, testklassen (= alle klassen met een naam van de vorm
...Test) en de inhoud van packageframeworkdienen ongewijzigd te blijven. -
Bij twijfel over de opdrachtomschrijving: bestudeer de unit-tests. Deze bepalen uiteindelijk welk gedrag goed en fout is. Let op: dit is geen "testontleedspel": je hoeft niet tegen de unit-tests te vechten totdat je uiteindelijk een pass krijgt! Als je het doel of het verwachte resultaat van een test niet snapt, schrijf dan in de Discussies en vraag de docenten.
-
De unit-tests controleren ook op robuustheid van implementaties van methode
receive; deze implementaties dienen gebruik te maken vanIllegalReceiveExceptionom ongewenste situaties te signaleren (bijvoorbeeld: de ontvangst van een tiende bericht in een ronde Steen-Papier-Schaar met slechts negen deelnemers). Echter, algemene eisen waaraan de implementatie van elk gedistribueerd algoritme moet voldoen, mogen weggelaten worden (bijvoorbeeld: bij een methodeaanroepp.receive(m,c)is het niet nodig om te controleren ofmencnietnullzijn, en ofcdaadwerkelijk een inkomend kanaal is vanp). -
Om unit-tests uit te voeren:
- Open de klasse waarin de unit-tests gedefinieerd zijn.
- Klik:
Run(menubalk) >Coverage
De opdracht: Implementeer methoden init en receive in klasse week1.RockPaperScissorsProcess.
Voldoende/onvoldoende? Alle unit-tests in klasse week1.RockPaperScissorsProcessTest dienen te slagen.
Aanwijzingen:
-
Gebruik de informele beschrijving en/of pseudocode die tijdens Hoorcollege 1 is behandeld. Wanneer een proces van elk ander proces een item heeft ontvangen, print het
<win> <lose>(gebruik methodeprintvan superklasseframework.Process). -
Klasse
week1.Itemrepresenteert items (steen, papier, of schaar). -
Klasse
week1.RockPaperScissorsMessagerepresenteert berichten met steen, papier, of schaar als inhoud.
De opdracht: Implementeer methoden init en receive in klasse week1.RockPaperScissorsCheatingProcess.
Voldoende/onvoldoende? Alle unit-tests in klasse week1.RockPaperScissorsCheatingProcessTest dienen te slagen.
Aanwijzingen:
- Het is de bedoeling om Cheating Guldo, wiens lokaal transitiesysteem is besproken tijdens Hoorcollege 1, te veralgemeniseren, volgens de volgende beschrijving:
- Een algemeen valsspelend proces
pontvangt eerst van elk ander proces een item. - Wanneer
pvan elk ander proces een item heeft ontvangen, kiestpeen eigen item zodanig dat het: in ieder geval niet verliest; en, wint als het kan winnen. (Met meer dan twee spelers kan het zijn datpgeen item kan kiezen zodanig dat hij wint, maarpkan wel voorkomen dat hij verliest.) - Vervolgens verstuurt
pzijn gekozen item naar elk ander proces. - Tenslotte print
p, zoals eerlijke processen,<win> <lose>(gebruik methodeprintvan superklasseframework.Process).
- Een algemeen valsspelend proces
De opdracht: Implementeer methoden init en receive in klasse week1.RockPaperScissorsMultiRoundsProcess.
Voldoende/onvoldoende? Alle unit-tests in klasse week1.RockPaperScissorsMultiRoundsProcessTest dienen te slagen.
Aanwijzingen:
-
Dit is een uitbreiding op 1a; de eerder toegevoegde implementaties van
initenreceivevan klasseweek1.RockPaperScissorsProcesskunnen daarom als basis worden genomen (hoewel het aannemelijk is dat aanzienlijke wijzigingen noodzakelijk zijn). Het idee van de uitbreiding is dat elk proces aan het eind van de huidige ronde bepaalt—op basis van zijn winnaar- en verliezerschap—of het meedoet aan de volgende ronde. In detail:- Als een proces winnaar is in de huidige ronde (= zijn item verslaat het item van minimaal een ander proces), en verliezer (= het item van minimaal een ander proces verslaat zijn item), dan doet het mee aan de volgende ronde.
- Als een proces winnaar is in de huidige ronde, maar geen verliezer, dan doet het niet mee aan de volgende ronde (sterker nog: er is geen volgende ronde). In dit geval is het proces winnaar van het hele spel, en print het
true(gebruik methodeprintvan superklasseframework.Process). - Als een proces verliezer is in de huidige ronde, maar geen winnaar, dan doet het niet mee aan de volgende ronde. In dit geval is het proces verliezer van het hele spel en print het
false. Wanneer het proces in het vervolg een bericht ontvangt, stuurt het datzelfde bericht terug naar de afzender. - Als een proces geen verliezer is in de huidige ronde, en geen winnaar, dan doet het mee aan de volgende ronde.
-
Neem aan dat kanalen de volgorde waarin berichten verstuurd zijn, behouden (FIFO).
-
Een complicatie is het fenomeen dat een proces "voor kan lopen" op andere processen. De volgende executie is, bijvoorbeeld, mogelijk:
- Guldo, in ronde 1, verstuurt
Item.ROCKnaar Recoome en Burter. - Recoome, in ronde 1, verstuurt
Item.PAPERnaar Guldo en Burter. - Burter, in ronde 1, verstuurt
Item.SCISSORSnaar Guldo en Recoome. - Recoome ontvangt
Item.ROCKenItem.SCISSORSvan Guldo en Burter; hij bepaalt vervolgens dat hij zowel winnaar als verliezer is in ronde 1 en doet daarom mee aan ronde 2. - Recoome, in ronde 2, verstuurt
Item.SCISSORSnaar Guldo en Burter. Recoome is nu dus al met ronde 2 begonnen, terwijl Guldo en Burter nog met ronde 1 bezig zijn. - Guldo, in ronde 1, ontvangt
Item.PAPERvan Recoome. - Guldo, in ronde 1, ontvangt
ITEM.SCISSORSvan Recoome. Guldo heeft nu dus, terwijl hij nog in ronde 1 is, Recoome's item uit ronde 2 ontvangen.
Er is aanvullend boekhoudwerk nodig om ervoor te zorgen dat goed omgegaan wordt met dit soort situaties.
- Guldo, in ronde 1, verstuurt
De opdracht: Implementeer methode hasExecution in klasse week2.GlobalTransitionSystem.
Voldoende/onvoldoende? Alle unit-tests in klasse week2.GlobalTransitionSystemsTest dienen te slagen.
Aanwijzingen:
-
Klasse
week2.Configurationis een attribuutloze klasse; elkConfiguration-object representeert een configuratie in een globaal transitiesysteem, maar de interne details zijn voor deze opdracht irrelevant (daarom: geen attributen). -
Klasse
week2.GlobalTransitionSystemheeft twee attributen:transitionseninitial. Attribuuttransitionsrepresenteert de transities in een globaal transitiesysteem. Enkele voorbeelden:- Als er een transitie is van configuratie
c1naar configuratiec2middels evente, dan geldt:c2.equals(transitions.get(c1).get(e)) - De events die kunnen plaatsvinden in configuratie
czijn:transitions.get(c).keySet() - De configuraties die met een transitie bereikt kunnen worden vanuit
czijn:transitions.get(c).values()
- Als er een transitie is van configuratie
-
Wanneer een configuratie geen uitgaande transities heeft, geldt:
transitions.get(c) == null -
Begrip van de code onder de "horizontale lijn" in klasse
week2.GlobalTransitionSystem(onder methodehasExecution) is onnodig voor deze opdracht.
De opdracht: Implementeer methoden CausalOrder (constructor) en toComputation in klasse week2.CausalOrder.
Voldoende/onvoldoende? Alle unit-tests in klasse week2.CausalOrderTest dienen te slagen.
Aanwijzingen:
-
Klasse
Eventis een abstracte klasse met subklassenSendEvent,ReceiveEvent, enInternalEvent; elkEvent-object representeert een (verzend-, verstuur-, of intern) event. MethodegetProcessretourneert het proces bij wie het event plaatsvindt; de subklassen hebben ook een aantal specifieke methoden die nuttig kunnen zijn bij het maken van deze opdracht. -
Klasse
Pairis een klasse met twee attributen:leftenright; elkPair-object representeert een causaal verband tussen twee events. Als eventacausaal geordend is voor eventb(dus:a≺b), dan wordt dat gerepresenteerd met eenPair-object waarvoor geldt:left.equals(a) && right.equals(b) -
Klasse
week2.CausalOrderheeft een attribuut:pairs. ElkCausalOrder-object representeert een causale ordening als een verzameling van causale verbanden. -
Methode
CausalOrder(constructor) dient attribuutpairste vullen met alle causale verbanden die afgeleid kunnen worden vansequence, volgens de twee regels die besproken zijn tijdens Hoorcollege 1. Houdt hierbij de volgende aanvullende eis aan:- Als events
a,b, encplaatsvinden bij hetzelfde proces, bevat de causale ordeninga≺b, enb≺c, maar nieta≺c(omdat die laatste in principe kan worden afgeleid van de eerste twee door de transitieve afsluiting te berekenen; dit is geen onderdeel van deze opdracht).
- Als events
-
Methode
toComputationdient de unieke verzameling van alle executies (= lijst van events) op te leveren die enkel verschillen in de volgorde van concurrent events, op basis van de paren in de causale ordening, en op basis van parameterevents(om precies te zijn: elke executie is een permutatie van events inevents). Performance is hierbij geen evaluatiecriterium; een recursieve brute-force-aanpak is toegestaan. -
Begrip van de code onder de "horizontale lijn" in klasse
week2.CausalOrder(onder methodetoComputation) is onnodig voor deze opdracht.
De opdracht: Implementeer methoden LamportsClock (constructor) en VectorClock (constructor) in klassen week2.LamportsClock en week2.VectorClock.
Voldoende/onvoldoende? Alle unit-tests in klassen week2.LamportsClockTest en week2.VectorClockTest dienen te slagen.
Aanwijzingen:
-
Klassen
week2.LamportsClockenweek2.VectorClockzijn subklassen van abstracte klasseweek2.LogicalClock. Deze abstracte klasse heeft een attribuut:timestamps. Dit attribuut houdt per event een klokwaarde bij. De klokwaarden zijn van typeT. Inweek2.LamportsClockisTgeïnstantieerd metInteger(elke klokwaarde van Lamport's Clock is een getal); inweek2.VectorClockisTgeïnstantieerd metMap<Process, Integer>(elke klokwaarde van de Vector Clock is een getal voor elk proces; informeel noemt men dit een vector van getallen, maar in Java is dit het makkelijskt te representeren met eenMap). -
Methoden
LamportsClock(constructor) enVectorClock(constructor) dienen attribuuttimestamps(in de superklasse) te vullen volgens de regels van Lamport's Clock en de Vector Clock. Gebruik hiervoor methoden uit de superklasse (in ieder gevaladdTimestamp; optioneel, naar eigen inzicht,containsTimestampengetTimestamp). -
Begrip van de code onder de "horizontale lijn" in klasse
week2.VectorClock(onder de constructor) is onnodig voor deze opdracht.
De opdracht: Implementeer methoden init en receive in klassen week34.ChandyLamportProcess, week34.ChandyLamportInitiator, en week34.ChandyLamportNonInitiator, volgens het Chandy-Lamport-algoritme.
Voldoende/onvoldoende? Alle unit-tests in klasse week34.ChandyLamportProcessTest dienen te slagen.
Aanwijzingen:
-
Klasse
week34.SnapshotProcessis een superklasse die processen representeert die zich gedragen volgens een snapshot-algoritme (Chandy-Lamport of Lai-Yang). De klasse heeft drie attributen:started(trueals het proces een lokale snapshot gestart is),finished(trueals het proces een lokale snapshot gefinisht is), enchannelStates(voor elk kanaalceen lijst met berichten die op het moment van de lokale snapshot onderweg zijn langsc). Deze attributen kunnen geïnspecteerd en gemanipuleerd worden middels de methoden van klasseweek34.SnapshotProcess. -
Klassen
week34.ChandyLamportProcess,week34.ChandyLamportInitiator, enweek34.ChandyLamportNonInitiatorzijn subklassen vanweek34.SnapshotProcess. Strikt genomen isweek34.ChandyLamportProcessredundant: het gedrag van een initiator en non-initiators in het Chandy-Lamport-algoritme kan prima gedefinieerd worden in methodeninitenreceivevan klassenweek34.ChandyLamportInitiatorenweek34.ChandyLamportNonInitiator, zonder gebruik te maken vanweek34.ChandyLamportProcess. Echter, om codeduplicatie te voorkomen, kan het handig zijn om gemeenschappelijk gedrag (tussen initiator en non-initiators) onder te brengen inweek34.ChandyLamportProcess. Hierdoor kan het gebeuren dat implementaties vaniniten/ofreceivein de subklassen leeg zijn (of alleensuper.<methode>(...)aanroepen); dat is prima. -
Methode
receivevanweek34.ChandyLamportProcess,week34.ChandyLamportInitiator, enweek34.ChandyLamportNonInitiatorwordt als het goed is (denk aan robuustheid) aangeroepen met eenChandyLamportBasicMessage-object of eenChandyLamportControlMessage-object (= een marker). -
Om een lokaal snapshot te starten/finishen, dient methode
startSnapshot/finishSnapshot(gedefinieerd in klasseweek34.SnapshotProcessen toegankelijk in de subklassen) te worden aangeroepen. -
Lokale toestanden worden niet expliciet vastgelegd (neem aan dat dit onderdeel is van methode
startSnapshot). Om kanaaltoestanden vast te leggen, dient methoderecord(gedefinieerd in klasseweek34.SnapshotProcessen toegankelijk in de subklassen) te worden aangeroepen. -
In de beschrijving van het algoritme tijdens Hoorcollege 2 is een kunstmatige communicatie van de initiator naar zichzelf toegevoegd (om de beschrijving op de slide in te kunnen korten); negeer deze communicatie in de implementatie.
De opdracht: Implementeer methoden init en receive in klassen week34.LaiYangProcess, week34.LaiYangInitiator, en week34.LaiYangNonInitiator, volgens het Lai-Yang-algoritme.
Voldoende/onvoldoende? Alle unit-tests in klasse week34.LaiYangProcessTest dienen te slagen.
Aanwijzingen:
-
De eerste twee aanwijzingen bij deelopdracht 3a zijn ook van toepassing op deze deelopdracht.
-
Methode
receivevanweek34.LaiYangProcess,week34.LaiYangInitiator, enweek34.LaiYangNonInitiatorwordt als het goed is (denk aan robuustheid) aangeroepen met eenLaiYangBasicMessage-object of eenLaiYangControlMessage-object. -
Neem voor de implementatie van elk proces aan dat hij nul basisberichten heeft verstuurd wanneer het algoritme begint.
-
De implementatie van het piggybacken van
trueoffalseop basisberichten valt buiten deze deelopdracht. -
De laatste drie aanwijzingen bij deelopdracht 3a zijn ook van toepassing op deze deelopdracht.
De opdracht: Implementeer methoden init en receive in klassen week56.RingProcess, week56.RingInitiator, en week56.RingNonInitiator, volgens het ring-algoritme.
Voldoende/onvoldoende? Alle unit-tests in klasse week56.RingProcessTest dienen te slagen.
Aanwijzingen:
-
Klasse
week56.WaveProcessis een superklasse die processen representeert die zich gedragen volgens een wave-algoritme. De klasse heeft een attribuut:active(truetotdat het proces lokaal klaar is met het algoritme). Dit attribuut kan geïnspecteerd en gemanipuleerd worden met methodenisActive,isPassive, endone. -
Klassen
week56.RingProcess,week56.RingInitiator, enweek56.RingNonInitiatorzijn subklassen vanweek56.WaveProcess. Strikt genomen isweek56.RingProcessredundant: het gedrag van een initiator en non-initiators in het ring-algoritme kan prima gedefinieerd worden in methodeninitenreceivevan klassenweek56.RingInitiatorenweek56.RingNonInitiator, zonder gebruik te maken vanweek56.RingProcess. Echter, om codeduplicatie te voorkomen, kan het handig zijn om gemeenschappelijk gedrag (tussen initiator en non-initiators) onder te brengen inweek56.RingProcess. Hierdoor kan het gebeuren dat implementaties vaniniten/ofreceivein de subklassen leeg zijn (of alleensuper.<methode>(...)aanroepen); dat is prima. -
Methode
receivevanweek56.RingProcess,week56.RingInitiator, enweek56.RingNonInitiatorwordt als het goed is (denk aan robuustheid) aangeroepen met eenTokenMessage-object. -
Om aan te geven dat een proces lokaal klaar is met het algoritme, dient methode
done(gedefinieerd in klasseweek56.WaveProcess)te worden aangeroepen op het juiste moment. -
In de beschrijving van het algoritme tijdens Hoorcollege 3 is een kunstmatige communicatie van de initiator naar zichzelf toegevoegd (om de beschrijving op de slide in te kunnen korten); negeer deze communicatie in de implementatie.
De opdracht: Implementeer methoden init en receive in klassen week56.TarryProcess, week56.TarryInitiator, en week56.TarryNonInitiator, volgens Tarry's algoritme.
Voldoende/onvoldoende? Alle unit-tests in klasse week56.TarryProcessTest dienen te slagen.
Aanwijzingen:
- Alle aanwijzingen bij deelopdracht 4a zijn ook van toepassing op deze deelopdracht.
De opdracht: Implementeer methoden init en receive in klassen week56.DepthFirstSearchProcess, week56.DepthFirstSearchInitiator, en week56.DepthFirstSearchNonInitiator, volgens het dfs-algoritme.
Voldoende/onvoldoende? Alle unit-tests in klasse week56.DepthFirstSearchProcessTest dienen te slagen.
Aanwijzingen:
- Alle aanwijzingen bij deelopdracht 4a zijn ook van toepassing op deze deelopdracht.
De opdracht: Implementeer methoden init en receive in klassen week56.DepthFirstSearchExtraPiggybackProcess, week56.DepthFirstSearchExtraPiggybackInitiator, en week56.DepthFirstSearchExtraPiggybackNonInitiator, volgens het dfs-algoritme + extra piggybacking.
Voldoende/onvoldoende? Alle unit-tests in klasse week56.DepthFirstSearchExtraPiggybackProcessTest dienen te slagen.
Aanwijzingen:
-
Alle aanwijzingen bij deelopdracht 4a zijn ook van toepassing op deze deelopdracht.
-
Methode
receivevanweek56.DepthFirstSearchExtraPiggybackProcess,week56.DepthFirstSearchExtraPiggybackInitiator, enweek56.DepthFirstSearchExtraPiggybackNonInitiatorwordt als het goed is (denk aan robuustheid) aangeroepen met eenTokenWithIdsMessage-object. -
Gebruik procesnamen (methode
getName(), gedefinieerd in klasseframework.Process) als ids (methodeaddId, gedefinieerd in klasseweek56.TokenWithIdsMessage).
De opdracht: Implementeer methoden init en receive in klassen week56.DepthFirstSearchExtraControlProcess, week56.DepthFirstSearchExtraControlInitiator, en week56.DepthFirstSearchExtraControlNonInitiator, volgens het dfs-algoritme + extra controleberichten.
Voldoende/onvoldoende? Alle unit-tests in klasse week56.DepthFirstSearchExtraControlProcessTest dienen te slagen.
Aanwijzingen:
-
Alle aanwijzingen bij deelopdracht 4a zijn ook van toepassing op deze deelopdracht.
-
Methode
receivevanweek56.DepthFirstSearchExtraControlProcess,week56.DepthFirstSearchExtraControlInitiator, enweek56.DepthFirstSearchExtraControlNonInitiatorwordt als het goed is (denk aan robuustheid) aangeroepen met eenTokenMessage-object, eenInfoMessage-object, of eenAckMessage-object.
De opdracht: Implementeer methoden init en receive in klassen week78.BrachaTouegProcess, week78.BrachaTouegInitiator, en week78.BrachaTouegNonInitiator, volgens het Bracha-Toueg-algoritme.
Voldoende/onvoldoende? Alle unit-tests in klasse week78.BrachaTouegProcessTest dienen te slagen.
Aanwijzingen:
-
Klasse
week78.DeadlockDetectionProcessis een superklasse die processen representeert die zich gedragen volgens een deadlock-detectie-algoritme. De klasse heeft drie attributen:inRequests(verzameling van kanalen waarlangs een verzoek ontvangen is);outRequests(verzameling van kanalen waarlangs een verzoek verstuurd is);requests(het aantal verstuurde verzoeken dat toegekend dient te worden). Deze attributen zijnprotected, dus ze kunnen direct geïnspecteerd en gemanipuleerd worden vanuit subklassen. -
Klassen
week78.BrachaTouegProcess,week78.BrachaTouegInitiator, enweek78.BrachaTouegNonInitiatorzijn subklassen vanweek78.DeadlockDetectionProcess. Strikt genomen isweek78.BrachaTouegProcessredundant: het gedrag van een initiator en non-initiators in het Bracha-Toueg-algoritme kan prima gedefinieerd worden in methodeninitenreceivevan klassenweek78.BrachaTouegInitiatorenweek78.BrachaTouegNonInitiator, zonder gebruik te maken vanweek78.BrachaTouegProcess. Echter, om codeduplicatie te voorkomen, kan het handig zijn om gemeenschappelijk gedrag (tussen initiator en non-initiators) onder te brengen inweek78.BrachaTouegProcess. Hierdoor kan het gebeuren dat implementaties vaniniten/ofreceivein de subklassen leeg zijn (of alleensuper.<methode>(...)aanroepen); dat is prima. -
Methode
receivevanweek78.BrachaTouegProcess,week78.BrachaTouegInitiator, enweek78.BrachaTouegNonInitiatorwordt als het goed is (denk aan robuustheid) aangeroepen met eenNotifyMessage-object, eenDoneMessage-object, eenGrantMessage-object, of eenAckMessage-object. -
De initiator dient, wanneer het algoritme termineert,
truete printen als hij geen deadlock heeft gedetecteerd, en andersfalse(gebruik methodeprintvan superklasseframework.Process). -
In de beschrijving van het algoritme tijdens Hoorcollege 4 is een kunstmatige communicatie van de initiator naar zichzelf toegevoegd (om de beschrijving op de slide in te kunnen korten); negeer deze communicatie in de implementatie.
-
Zorg ervoor dat de implementatie ook om kan gaan met N-uit-M-verzoeken met 1<N<M. NB: Dit is niet besproken tijdens Hoorcollege 4 (en ook niet in het tekstboek); bedenk de generalisatie zelf (er zijn enkele unit-tests waarin deze situatie zich voordoet).
Wanneer alle unit-tests van alle opdrachten slagen, kunnen de implementaties ingeleverd worden, volgens deze stappen:
-
In de VM, open een terminal en voer uit:
cd /home/ou tar -czf ib2302.tar.gz ib2302 -
Op Brightspace, stuur de zojuist gemaakte
/home/ou/ib2302.tar.gzin met het formulier onderCursus>Inhoud>Programmeeropdrachten>Instructie. -
Het reflectieverslag kan ingestuurd worden via Brighspace
Cursus>Inhoud>Programmeeropdrachten>Reflectieverslag.