I am writing an XML-RPC module in OCaml using the xml-rpc-light library. I would like to have a server that can receive parallel requests and collect data sent by all requests in a common "state". To be specific, but simplifying the real problem, suppose the server provides a function
send : int -> bool
which sends an integer and returns true on success and false on error, and that the server wants to keep a list of all the integers that have ever been called (including duplicates).
I understand the XML-RPC part. Parts that are difficult for me to implement in OCaml synchronize various server-side client calls so that they are thread safe.
I wrote a client class
class client = object val xr_client = new XmlRpc.client "http://localhost:11111" method send n = xr_client#call "send_integer" [`Int n] in end
which calls the corresponding send_integer remote method with some integer n .
I also wrote a server class
class server = object(self) val mutable state = (ref [] : int list ref) val xr_server = new XmlRpcServer.netplex () val m = Mutex.create () method send n = let send_sync sn = (Mutex.lock m; s := n::!s; Mutex.unlock m) in (send_sync state n; `Boolean true) method init () = xr_server#register "send_integer" ~signatures:[[`Int; `Boolean]] (function | [`Int x] -> self#send x; | _ -> XmlRpcServer.invalid_params ()); xr_server#run () end
which has a mutable state to store all integers and a send method to actually make client calls. For each client call, I just update the state. But if the second call arrives before the second is finished, I ran into thread safety issues. That's why I added the Mutex bit, which uses the mutex of one class to get a lock when updating state.
My questions:
- Will synchronization be achieved?
- Are there any tidier ways to do this?
- Is synchronization already built into the XML-RPC server, which makes all this unnecessary?
source share