Hello,
I am porting a project previously based on a synchronous nethttpd server to Opium.
I’d first like to thank @rgrinberg for Opium, which is so much easier to set up than nethttpd :). Since I am not much used to event programming or Lwt, I have some questions.
First question: When receiving e.g. a POST request with a body, the body seems to come as a string Lwt_stream.t. Is there a “good way” to work with such body ? I could come with two ways, both using Lwt_main.run:
let body = req.body
|> Cohttp_lwt.Body.to_string
|> Lwt_main.run
... use body variable
(
match%lwt
req.body
|> Cohttp_lwt.Body.to_string
>|= Yojson.Safe.from_string
>|= my_type_of_yojson
with
| Ok res -> Lwt.return "body decoded"
| Error e -> Lwt.return "bad body"
)
|> Lwt_main.run
Second question: the web server provides an interface to a kind of simulator, that is an object that is not designed to be accessed concurrently. Will Mutex be enough to deal with this, or is there anything else i should know ?
Edit:
Third question (altough I guess I would eventually find out): I am using my own command line arguments, so I don’t use Opium’s built in. I did not see an easy way to pass e.g. the debug argument for the Opium App, is there one ?
All your Lwt code will run in the main thread. This means that once you call a function in your simulator object’s API, that function will run to completion without any interference from anything else that needs to run later in the main thread, like processing more requests with Opium, or running anything else that is using Lwt.
So, you only need a mutex if you need to protect a sequence of two or more calls to the simulator object’s API. Even then, you only need a mutex if your code does an Lwt bind between those two calls.
The standard Mutex is wrong here, because it prevents interference between different system threads, while, again, all Lwt code runs in the main thread.
Slightly off topic but I would be interested to look at a small web app that uses Opium where the HTML is handled client side and not generated by the server. Looking trough Opam I could not find one, the Opium repo does not list any, and its examples are a bit too minimal.
I don’t have a specific example with Opium but you can have a client side driven app by serving your Javascript file using opium’s static file serving middleware.
After that any of the client side examples should be application. You could use tyxml with jsoo, incr_dom, ocaml-vdom, or any javascript client side solution.