11 Compile Server Application

We now develop an application where a client can send an Oz file containing a functor expression to a compile server and gets back the corresponding compiled functor. The server provides a compilation service.

11.1 Server ozc-server.oz

The compile server is compiled as follows:

ozc -x ozc-server.oz -o ozc-server.exe

and can be started with the command line:

ozc-server.exe --ticketfile file

the server returns yes(F) where F is a functor value, or no(Msgs), if compilation failed, where Msgs are the error messages obtained from the compiler's interface.

   Compiler Application
   Server at 'server.ozf' 
   class OZC 
      prop locking
      feat engine interface
      meth init 
         self.engine    = {New Compiler.engine    init}
         self.interface = {New Compiler.interface init(self.engine)}
         {self.engine enqueue(setSwitch(expression true))}
      meth compile(VS $)
         lock F in 
             enqueue(feedVirtualString(VS return(result:F)))}
            {Wait {self.engine enqueue(ping($))}}
            if {self.interface hasErrors($)} then 
               no({self.interface getMessages})
            else yes(F) end 
   Service = {New OZC init}
   Args = {Application.getCmdArgs
              ticketfile(single char:&t type:string optional:false))}
   {Server.start Service Args.ticketfile}

11.2 Client ozc-client.oz

The client can be compiled as follows:

ozc -x ozc-client.oz -o ozc-client.exe

and can be invoked with:

ozc-client.exe --url=URL --in=InFile --out=OutFile

It loads the compile server's ticket from URL, uses it to obtain the forwarding procedure, applies it to the textual contents of InFile and saves the returned functor value in OutFile. Note that we convert the string (i. e. list) representation of the file's contents to a byte string for more efficient transmission; this is not necessary, but greatly reduces the amount of data that needs to be transmitted.

import Application Open Pickle Connection
   Args = {Application.getCmdArgs
              url( single type:string optional:false)
              'in'(single type:string optional:false)
              out( single type:string optional:false))}
   File = {New Open.file init(name:Args.'in')}
   Text = {File read(list:$ size:all)}
   {File close}
   OZC  = {Connection.take {Pickle.load Args.url}}
   case {OZC compile({ByteString.make Text} $)}
   of yes(F) then 
      {Pickle.save F Args.out}
      {Application.exit 0}
   elseof no(Msgs) then raise ozc(Msgs) end end 

Denys Duchier, Leif Kornstaedt and Christian Schulte
Version 1.4.0 (20080702)