# 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