Servern ska göra det möjligt att registrera Erlang-processer under ett givet namn, slå upp ett namn (om det finns), fråga vilka namn som finns registrerade för tillfället, samt avregistrera ett namn. Servern ska spåra sina registrerade processer med hjälp av processlänkar, så att om en sådan dör, ska servern avregistrera namnet.
Poängen med en server som denna är att den skapar ett isolerat
"subspace" av globalt registrerade namn. Erlang-systemets vanliga
globala registrering skiljer inte på olika sorters processer, så det är
inte uppenbart vad en process gör, även om man ser att den är globalt
registrerad. Man kan däremot använda en namnserver för att registrera
t.ex. enbart processer som hanterar skrivare. Om servern registreras
globalt under namnet printers
, så kan man fråga den "vilka
skrivare finns registrerade", och sedan välja en viss skrivare att
kontakta för att göra ett jobb. Er server kommer att komma till nytta i
uppgift 2.
Uppgiften redovisas i form av ett e-mail till Richard innehållande sökvägen till källkoden för servern. Se till att filerna är läsbara!
Ni får fritt knycka kod ur Erlang-boken (men lägg då helst in kommentarer som talar om varifrån det kommer, om inte annat så som en god vana). Om ni lånar från andra källor så måste ni ange dem uttryckligen.
nameserver
, som ska
exportera följande funktioner:
start(Name) -> ok | {error, already_started} |
{error, Reason}
Name = atom()
Pid = pid()
Reason = term()
Startar servern som en ny process och registrerar den globalt
under namnet Name
. Om allt går väl returneras
ok
.
Om det redan finns en process registrerad under detta namn
returneras {error, {already_started, Pid}}
, där
Pid
är den existerande processens id.
Om ni detekterar att det av någon annan anledning inte går att
starta servern, returnerar ni {error, Reason}
, där
Reason
indikerar felet.
Observera: Flera processer kan försöka starta en server
samtidigt! Även om ni först testar att Name
inte
finns i det globala registret, så kan registreringen
misslyckas därför att någon annan har stuckit emellan. Ni måste
hantera detta, och ge ett korrekt returvärde.
stop(Name) -> ok
Name = atom()
Terminerar serverprocessen med globalt namn Name
.
(Detta avregistrerar automatiskt namnet.) Returnerar alltid
ok
.
register(Server, Name, Pid, Description) ->
ok | {error, Reason}
Server = atom()
Name = string()
Pid = pid()
Description = string()
Reason = term()
Registrerar processen Pid
hos servern
Server
under namnet Name
. Notera att
Name
ska vara en sträng (dvs. en lista av
teckenkoder), inte en atom. Description
är en sträng som
ska lagras tillsammans med Pid
, så servern kan
presentera en kort textbeskrivning för varje registrerad process.
Om allt går väl returneras ok
, och i annat fall
(t.ex., om namnet var upptaget) returneras
{error, Reason}
.
lookup(Server, Name) -> {ok, Pid} | {error, Reason}
Server = atom()
Name = string()
Reason = term()
Slår upp namnet Name
hos Server
. Om
namnet hittas, returneras {ok, Pid}
för motsvarande
Pid
, och annars returneras {error, Reason}
.
unregister(Server, Name) -> ok
Server = atom()
Name = string()
Avregistrerar namnet Name
hos Server
.
Returnerar alltid ok
oavsett vad som händer.
registered(Server) -> {ok, List} | {error, Reason}
Server = atom()
List = [{Name, Description}]
Name = string()
Description = string()
Reason = term()
Returnerar {ok, List}
där List
är
listan av alla namn och tillhörande beskrivningar
registrerade hos Server
. Om något går fel
returneras {error, Reason}
.
Kom ihåg för framtida bruk: så snart ni har fått
informationen från servern finns det en möjlighet att den redan är
föråldrad. Man kan inte lita på att lookup
kommer att
lyckas även om namnet fanns där nyss.
nameserver
-modulen finns och ser ut som ovan.