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.

functor 
import 
   Compiler Application
   Server at 'server.ozf' 
define 
   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))}
      end 
      meth compile(VS $)
         lock F in 
            {self.engine
             enqueue(feedVirtualString(VS return(result:F)))}
            {Wait {self.engine enqueue(ping($))}}
            if {self.interface hasErrors($)} then 
               no({self.interface getMessages})
            else yes(F) end 
         end 
      end 
   end 
   Service = {New OZC init}
   Args = {Application.getCmdArgs
           record(
              ticketfile(single char:&t type:string optional:false))}
   {Server.start Service Args.ticketfile}
end 

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.

functor 
import Application Open Pickle Connection
define 
   Args = {Application.getCmdArgs
           record(
              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 
end 


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