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]