Distributed programming

From Rosetta Code
Revision as of 09:03, 13 September 2007 by 88.6.9.210 (talk)
Task
Distributed programming
You are encouraged to solve this task according to the task description, using any language you may know.

Given two computers on a network, send messages between them. The protocol used may be language-specific or not, and should be suitable for general distributed programming.

E

Protocol: Pluribus

This service cannot be used except by clients which know the URL designating it, messages are encrypted, and the client authenticates the server. However, it is vulnerable to denial-of-service by any client knowing the URL.

Server

(The protocol is symmetric; this program is the server only in that it is the one which is started first and exports an object.)

def storage := [].diverge()

def logService {
  to log(line :String) {
    storage.push([timer.now(), line])
  }
  to search(substring :String) {
    var matches := []
    for [time, line] ? (line.startOf(substring) != -1) in storage {
      matches with= [time, line]
    }
    return matches
  }
}

introducer.onTheAir()
def sturdyRef := makeSturdyRef.temp(logService)
println(<captp>.sturdyToURI(sturdyRef))
interp.blockAtTop()

This will print the URL of the service and run it until aborted.

Client

The URL provided by the server is given as the argument to this program.

def [uri] := interp.getArgs()
introducer.onTheAir()
def sturdyRef := <captp>.sturdyFromURI(uri)
def logService := sturdyRef.getRcvr()

logService <- log("foot")
logService <- log("shoe")

println("Searching...")
when (def result := logService <- search("foo")) -> {
  for [time, line] in result {
    println(`At $time: $line`)
  }
}

JoCaml

Minimalistic distributed logger with synchronous channels using the join calculus on top of OCaml.

Server

 open Printf

 let create_logger () =
   def log(text) & logs(l) =
       printf "Logged: %s\n%!" text;
       logs((text, Unix.gettimeofday ())::l) & reply to log
 
    or search(text) & logs(l) =
       logs(l) & reply List.filter (fun (line, _) -> line = text) l to search
   in
     spawn logs([]);
     (log, search)
 
 def wait() & finished() = reply to wait
 
 let register name service = Join.Ns.register Join.Ns.here name service

 let () =
   let log, search = create_logger () in
     register "log" log;
     register "search" search;
     Join.Site.listen (Unix.ADDR_INET (Join.Site.get_local_addr(), 12345));
     wait ()

Client

 open Printf

 let ns_there = Join.Ns.there (Unix.ADDR_INET (Join.Site.get_local_addr(), 12345))

 let lookup name = Join.Ns.lookup ns_there name
 
 let log : string -> unit = lookup "log"
 let search : string -> (string * float) list = lookup "search"

 let find txt =
   printf "Looking for %s...\n" txt;
   List.iter (fun (line, time) ->
                printf "Found: '%s' at t = %f\n%!" (String.escaped line) time)
     (search txt)

 let () =
   log "bar";
   find "foo";
   log "foo";
   log "shoe";
   find "foo"