Home Papers Reports Projects Code Fragments Dissertations Presentations Posters Proposals Lectures given Course notes
<< 6. Transaction Basics in Borg8. Thread Based Error Handling: Synchronous Voting on a Distributed Whiteboard >>

7. A Distributed Scheme Interpreter

Werner Van Belle1 - werner@yellowcouch.org, werner.van.belle@gmail.com

1- Programming Technology Lab (PROG) Department of Computer Science (DINF) Vrije Universiteit Brussel (VUB); Pleinlaan 2; 1050 Brussel; Belgium

Abstract :  These are course notes I made to teach distributed systems for the VUB. I used them in 1999-2000, 2000-2001

Reference:  Werner Van Belle; A Distributed Scheme Interpreter;
See also:
The scehme evaluator and a number of solutions to the excercise


Info

Zoals reeds gezien is Java RMI een mooie taalondersteuning die toelaat op eenvoudige wijze communicatie tussen verschillende java processen te ondersteunen. (zonder dat we moeten rekening houden hoe objecten van de ene machine naar de andere verplaatst worden). Nochthans hebben we gemerkt dat peer to peer communicatie een niet zo triviale zaak is. Het stub systeem van java zorgt dat het genereren van code relatief onflexiebel gebeurt. Een mogelijkheid om dit probleem op te vangen zijn gedistribueerde interpreters.

Mocht u zelf een interpreter schrijven om een taal gedistribueerd te interpreteren:

  1. hoe zou u dit aanpakken ?

  2. bespreek hoe uw interpreter verschillende threads kan afhandelen ?

  3. hoe creeeren we processen ?

Mochten we nu willen verschillende (geinterpreteerde) programmas met elkaar laten communiceren: bespreek hoe we dit kunnen doen ?

  1. hoe refereren we naar onze communicatiepartner ? [name server]

  2. hoe behandelt deze binnenkomende berichten ? [multi-threaded/single-threaded met queue]

  3. hoe sturen we asynchrone berichten naar een communicatiepartner ?

  4. hoe sturen we synchrone berichten naar een communicatiepartner ? (remote function calls)

  5. hoe serializeren we de data die van het ene proces naar het ander moet ?

Met de huidige setup in mind gaan we eens kijken naar de eerder moeilijkere dingen:
  1. hoe sturen we een functie definitie door ?

  2. hoe sturen we een closure door ? [een closure is een functie gedefineerd binnen een bepaalde omgeving]

  3. hoe sturen we objecten (dictionaries, evaluerende closures) door naar een ander proces ? [super]

  4. Hoe sturen we referenties door ? Zowel referenties naar lokale objecten als remote objecten ?



De bedoeling van deze opgave is een scheme interpreter te maken die in staat is aan een andere scheme environment te connecteren. Bijvoorbeeld, als we de 'scheme shared environment' gestart hebben met het volgende programma in geevalueerd:

  (define version "Scheme Shared Environment v0.1")

zou een client in staat moeten zijn te starten, deze environment op te zoeken en de versie op te vragen. De client-code in dit geval zou er als volgt moeten uit zien:

  (display version)

Een andere mogelijkheid is dat een andere client bijvoobeeld een programmatje start

  (set! version "Something Else")

wat tot gevolg heeft dat de variable opde server zijde aangepast wordt.

De evaluator van waar we starten is geschreven in Java en bestaat uit de volgende klassen :

Maak de scheme evaluator gedistribueerd zodat we in staat zijn een cliente scheme machine te laten connecteren aan een remote scheme environment.

Opgave 2: Cons-celletjes

Nu we in staat zijn eenvoudige variabelen (zoals strings en getallen) op te vragen, kunnen we eens kijken naar de mogelijkheid wat ingewikkeldere variabelen op te vragen. Bijvoorbeeld cons-cellen.

Probeer op de server een lijst te definieren (define somelist '(10 20 30 40 50))

die we op de client proberen opvragen. (display somelist)

Het is duidelijk dat dit niet gaat. Hoe kunnen we dit oplossen ? Willen we alle cons-cellen serialiseren en opsturen naar de client of willen we enkel een referentie meegeven ?

Implementeer de oplossing waarbij de cons cellen effectief geserialiseerd worden. (Dit kan in java gemakkelijk gedaan worden door de Cons classe te markeren met de serializable interface)

Opgave 3: Closures/Natives

De atomaire data-types cons, string en numbers kunnen nu zonder probleem overgezet worden, hierbij steeds de volledige interconnectie graph meenemend. We kunnen een andere environment oproepen zoals nodig. We zullen nu kijken naar closures. Schrijf een functie op de server. Bv:

  (define (printversion)
    (display version))

Schrijf een client die deze printversion kan opvragen en printen. Hoe gaan we dit doen ?

  • Stel dat we de closure serialiseren en over den draad sturen. Wat voor gevolgen heeft dit ?
  • Stel dat we de closure doorgeven als referentie. Wat voor gevolgen heeft dit ?
  • Wat moet er volgens u gebeuren als de server de code (define troela display) heeft staan en de client deze troela opvraagt. Moeten we de native serialiseren ? Wat voor gevolgen heeft dit ?
  • Moeten we natives doorgeven als referenties ? Wat voor gevolgen heeft dit ?
  • Implementeer de oplossing waarbij zowel natives als closure op de server blijven. (Ergens is dit ook het meest logische daar de client eigenlijkniet met weten wat de server doet om iets klaar te krijgen.)

    Opgave 4: Java

    Start de volgende programma's (het zijn weer eens een Whiteboard Server en Whiteboard Client :-).

    Kan u verklaren waarom dit programma werkt ? Wat betekent dit voor onze Java-code ?

    'Whiteboard Client
    '-----------------
    (define naam
      (cond ((= clientnr 1) "walter")
            ((= clientnr 2) "wudolf")
            ((= clientnr 3) "rudolf")))
    
    (display "Joining as ")
    (display naam)
    
    (define (receivemessage txt)
      (display txt) (newline))
    
    (join naam receivemessage)
    
    (while #t (message naam))
    
    'Whiteboard Server
    '-----------------
    
    (define clientnr 1)
    (define clients '())
    (define (join who callback)
      (set! clients (cons callback clients))
      (display who)
      (display " joined")
      (newline)
      (set! clientnr (+ clientnr 1)))
    
    (define (resendmessage txt lst)
      (if (null? lst)
        '()
        (begin
          ((car lst) txt)
          (resendmessage txt (cdr lst)))))
    
    (define (message txt)
    (display "resending message ")
    (display txt)
    (resendmessage txt clients)
    (newline))

    http://werner.yellowcouch.org/
    werner@yellowcouch.org