JOCAML: Getting Started
First at all, you have to setup your environment (bash):
coffeepot Simple $ export PATH=$PATH:/projects/dci/jocaml/bin
coffeepot Simple $ export LIB=/projects/dci/jocaml/lib/ocaml:$LIB
There are several import tools you got to know:
The compiler we are going to use: joc.
The interpreter (good for debugging ): joctop
The name server: jocns [-port port_number]
The example we are going to use is based on the tutoral, chapter 2 Distributed programming. There are two programs, p.ml and q.ml, involved in this example.
When lookup or register is first used, the runtime attempts to communicate with its name server, using by default the IP address and port number provided in two environment variables JNSNAME and JNSPORT. If no name server is running, the lookup or register call fails. The IP address for the server (or its port number) can also be supplied as command-line parameters when the runtime is started.
Starting the name server by typeing "jocns". Then it will start at the local server with default port 20001.
coffeepot p3 $ jocns &
[1] 4138
coffeepot p3 $ Name server started at port 20001
Starting multicast server ...
coffeepot p3 $ Server started
The following example illustrates this with two machines. Let us assume that we
have a single machine "coffeepot.cs.rpi.edu" that is particularly good at
computing squares of integers; on this machine, we define a square function that
also prints something when it is called (so that we can keep track of what is
happening), and we register this function with key ``square'':
The program p.ml is shown below:
let def f x =
print_string ("["^string_of_int(x)^"] "); flush stdout;
reply x*x in
Ns.register "square" f vartype
;;
Join.server ()
Now let's compile it by joc, and then execute it:
coffeepot p3 $ joc p.ml -o p.out
File "p.ml", line 4, characters 24-31:
Warning: VARTYPE replaced by type
( int -> int) metatype
coffeepot p3 $ ./p.out
Using multicast
Querying name server coffeepot.cs.rpi.edu:20001
The joc is the compiler with join-calculus library. When you compile the program, you can use the option -o to specify the output name.
The "Join.server''
primitive tells the program to keep running after the completion of all local
statements, so that it can serve remote calls.
The other program, q.ml, relies on the
previous machine to compute squares; this program first looks up for the name
registered by "dishwasher.cs.rpi.edu", then performs some computations and
reports their results.
let sqr = Ns.lookup "square" vartype
;;
let def log (s,x) =
print_string ("q: "^s^"= "^string_of_int(x)^"\n"); flush stdout; reply
;;
let def sum (s,n) = reply (if n = 0 then s else sum (s+sqr(n),n-1))
;;
log ("sqr 3",sqr 3);
log ("sum 5",sum (0,5));
exit 0
Let's get it compiled and then execute it. Remember to set the environment variable JNSNAME to indicate the name server. You can also specify the port number of the name server by setting the environment variable JNSPORT.
dishwasher p3 $ export JNSNAME=coffeepot.cs.rpi.edu
dishwasher p3 $ joc q.ml -o q.out
File "q.ml", line 1, characters 29-36:
Warning: VARTYPE replaced by type
( int -> int) metatype
dishwasher p3 $ ./q.out
Using multicast
Querying name server coffeepot.cs.rpi.edu:20001
q: sqr 3= 9
q: sum 5= 55
dishwasher p3 $
At the same time, we can see something happened at the console of "coffeepot.cs.rpi.edu"
coffeepot p3 $ ./p.out
Using multicast
Querying name server coffeepot.cs.rpi.edu:20001
[3] [5] [4] [3] [2] [1]