OCaml Tutorial

Introduction

All Apache Thrift tutorials require that you have:

  1. The Apache Thrift Compiler and Libraries, see Download and Building from Source for more details.
  2. Generated the tutorial.thrift and shared.thrift files:
    thrift -r --gen ocaml tutorial.thrift
  3. Followed all prerequisites listed below.

Prerequisites

Client

open Arg
open Thrift
open Tutorial_types
open Shared_types

exception Die;;
let sod = function
    Some v -> v
  | None -> raise Die;;

type connection = {
  trans : Transport.t ;
  proto : Thrift.Protocol.t;
  calc : Calculator.client ;
}

let connect ~host port =
  let tx = new TSocket.t host port in
  let proto = new TBinaryProtocol.t tx in
  let calc = new Calculator.client proto proto in
    tx#opn;
    { trans = tx ; proto = proto; calc = calc }
;;

let doclient () =
  let cli = connect ~host:"127.0.0.1" 9090 in
  try
    cli.calc#ping ;
    Printf.printf "ping()\n" ; flush stdout ;
    (let sum = cli.calc#add (Int32.of_int 1) (Int32.of_int 1) in
       Printf.printf "1+1=%ld\n" sum ;
       flush stdout) ;
    (let w = new work in
       w#set_op Operation.DIVIDE ;
       w#set_num1 (Int32.of_int 1) ;
       w#set_num2 (Int32.of_int 0) ;
       try
	 let quotient = cli.calc#calculate (Int32.of_int 1) w in
	   Printf.printf "Whoa? We can divide by zero!\n" ; flush stdout
       with InvalidOperation io ->
	 Printf.printf "InvalidOperation: %s\n" io#grab_why ; flush stdout) ;
    (let w = new work in
       w#set_op Operation.SUBTRACT ;
       w#set_num1 (Int32.of_int 15) ;
       w#set_num2 (Int32.of_int 10) ;
       let diff = cli.calc#calculate (Int32.of_int 1) w in
	 Printf.printf "15-10=%ld\n" diff ; flush stdout) ;
    (let ss = cli.calc#getStruct (Int32.of_int 1) in
       Printf.printf "Check log: %s\n" ss#grab_value ; flush stdout) ;
    cli.trans#close
  with Transport.E (_,what) ->
    Printf.printf "ERROR: %s\n" what ; flush stdout
;;

doclient();;

Server

open Arg
open Thrift
open Tutorial_types
open Shared_types

exception Die;;
let sod = function
    Some v -> v
  | None -> raise Die;;

class calc_handler =
object (self)
  inherit Calculator.iface
  val log = Hashtbl.create 23
  method ping  = Printf.printf "ping()\n" ; flush stdout
  method add a b =
    Printf.printf"add(%ld,%ld)\n" (sod a) (sod b); flush stdout ;
    Int32.add (sod a) (sod b)
  method calculate logid w =
    let w = sod w in
      Printf.printf "calculate(%ld,{%ld,%ld,%ld})\n" (sod logid) (Operation.to_i w#grab_op) w#grab_num1 w#grab_num2; flush stdout ;
    let rv =
      match w#grab_op with
	  Operation.ADD ->
	    Int32.add w#grab_num1 w#grab_num2
	| Operation.SUBTRACT ->
	    Int32.sub w#grab_num1 w#grab_num2
	| Operation.MULTIPLY ->
	    Int32.mul w#grab_num1 w#grab_num2
	| Operation.DIVIDE ->
	    if w#grab_num2 = Int32.zero then
	      let io = new invalidOperation in
		io#set_whatOp (Operation.to_i w#grab_op) ;
		io#set_why "Cannot divide by 0" ;
		raise (InvalidOperation io)
	    else
	      Int32.div w#grab_num1 w#grab_num2 in

    let ss = new sharedStruct in
      ss#set_key (sod logid) ;
    let buffer = Int32.to_string rv in
      ss#set_value buffer ;
      Hashtbl.add log (sod logid) ss ;
      rv

  method zip =
    Printf.printf "zip()\n"; flush stdout

  method getStruct logid =
    Printf.printf "getStruct(%ld)\n" (sod logid) ; flush stdout ;
    Hashtbl.find log (sod logid)

end

let doserver () =
  let h = new calc_handler in
  let proc = new Calculator.processor h in
  let port = 9090 in
  let pf = new TBinaryProtocol.factory in
  let server = new TThreadedServer.t
		 proc
		 (new TServerSocket.t port)
		 (new Transport.factory)
		 pf
		 pf
  in
    server#serve
;;

doserver();;

Additional Information