lørdag 4. september 2010 Diverse prosjekter Ping Ring Samtidighet
Dette er starten på en artikkelserie jeg har kalt Ping Ring. Jeg skal lage et program for å overvåke at et sett med servere er i live, og gjennom en rekke blogposter vil du få se det samme programmet implementert i et utall programmeringsspråk: C#, Ruby, Clojure, Erlang med flere.
Målet er å studere og demonstrere ulikhetene mellom språkene. I hvilket språk er det enklest å implementere programmet? Hvilken implementasjon er lettest å forstå? Følg med over de neste par ukene, og du vil kanskje finne svaret.
Se for deg at du har en haug med servere som du ønsker å vite at er operative – at de kjører, og er tilgjengelige på nettverket. En mulig strategi er å installere et lite program på hver server som sende et lite ping i en ring, som i figuren nedenfor.
Om en server faller ut, vil ringen bli brutt. Dette vil man kunne oppdage to steder: Programmet som forsøker å pinge serveren som er ute vil ikke kunne opprette kontakt, og serveren etter den som er ute i ringen vil slutte å motta pings. Disse serverne kan da trigge en alarm og fortelle driftsteamet hvilken server som er nede.
Jeg har valgt denne oppgaven fordi den ikke er så veldig vanskelig å implementere, selv om jeg må bruke noen teknikker som ikke dukker opp så veldig ofte i vanlig applikasjonsutvikling. For å løse oppgaven vil jeg bruke tråding/samtidighet, og low-level socket/TCP-kommunikasjon. Dette vil kunne vise interessante ulikheter i de ulike språkene. Programmet krever derimot ingen komplekse algoritmer eller data-hierarkier, som ville kunne gjøre det spesielt fordelaktig å bruke en bestemt klasse programmeringsspråk (som OOP vs. FP).
Først noen begrensninger: Jeg kommer bare til å simulere at jeg har mange servere, så alle vil kjøre på localhost. Hver instans vil dermed bli identifisert med en port, og kan anta at all komunikasjon går på IP 127.0.0.1. Programmet skal kjøres som en konsoll-applikasjon, og tar fire parametre: (1) egen port, (2) porten til den neste serveren i ringen, (3) hvor mange sekunder det kan gå uten en ping før alarmen skal aktiveres, og (4) en indikator for om programmet skal starte med en ping (én av serverne må starte opp ringen).
Og for enkelhets skyld vil det å aktivere alarmen bare være å skrive en melding til konsoll-vinduet.
Programmet vil bestå av følgende, funksjonelle deler:
Programmet må kunne sende en ping til en bestemt port (den neste serveren). Et ping består av teksten "Ping from X", hvor X er porten det sendes fra. Sendingen skal skje fra en egen tråd, slik at det ikke påvirker programmets øvrige oppgaver. Programmet skal alltid vente ett sekund før ping sendes - vi må ikke overbelaste nettverket/serverne med pings.
Hvis den neste serveren i rekken er nede skal pingen feile, og programmet skal da melde fra om dette til konsollet.
Programmet skal lytte på sin egen port etter pings. Pings skal mottas og behandles i en egen tråd, slik at det ikke påvirker programmets øvrige oppgaver. Når en ping mottas skal meldingen skrives til konsollet, og en ping skal sendes videre til neste server.
Programmet skal ha en egen tråd som i et bestemt intervall, for eksempel hvert femte sekund, kontrollerer at serveren mottar pings. Hvor mange sekunder serveren kan stå uten å motta pings er ett av oppstartsargumentene. Hvis denne grensen overskrides skal programmet skrive en alarm til konsollet som sier hvor mange sekunder det har gått siden siste ping ble mottatt. Det skal også sendes en ny ping for å forsøke å vekke ringen til live igjen.
Under oppstart skal programmet lese inn argumentene og starte opp de nødvendige trådene. Det skal også identifisere seg ved å skrive ut sin egen port til konsoll-vinduet. Og hvis det siste argumentet er "true" skal det sendes en initiell ping for å starte opp ringen.
Som jeg sa i starten skal jeg implementere dette programmet i en rekke, ulike programmeringsspråk. Vi kan forestille oss at vi har en overivrig systemansvarlig som nekter oss å kjøre annet enn C#-kode på C#-serveren, Ruby-kode på Ruby-serveren osv., og at vi derfor MÅ implementere mange varianter :P
Jeg kommer til å poste artiklene i rask rekkefølge, så følg nøye med i en uke eller to fremover.
Hvis du har lyst til å forsøke deg på en implementasjon selv kan det være lurt å gjøre det før du ser noen av mine implementasjoner.., så kan du i stedet sammenligne etterpå. I så fall er det kult om du gjør implementasjonen din tilgjengelig på pastie, CodeTidy, mysticpaste, Gist eller en annen pastebin, og deler linken med oss andre i en kommentar.