[ANN] Eliom 11 and Ocsigen Start 7

Eliom 11 and Ocsigen Start 7 have been released a few weeks ago.
These versions follow the recent release of Ocsigen Server 6 and leverage its new configuration API to make it easier to use it as a library, without a configuration file.

Here is an example of a simple OCaml app generating a Web page from server side (and serving static pages from directory "local/var/www/mysite"):

let f _ () =
  Lwt.return
    Eliom_content.Html.F.(html (head (title (txt "")) [])
                               (body [h1 [txt "Hello"]]))

let myservice =
  Eliom_service.create
    ~path:(Eliom_service.Path [])
    ~meth:(Eliom_service.Get Eliom_parameter.any)
    ()

let () = Eliom_registration.Html.register ~service:myservice f

let () = Ocsigen_server.start 
    [ Ocsigen_server.host
       [ Staticmod.run ~dir:"local/var/www/mysite" ()
       ; Eliom.run () ] ]

To use it, just install Eliom and your favorite version of Ocipersist, then create a new Dune project:

opam install ocsipersist-sqlite-config eliom
dune init project mysite

Put the code above in file bin/mysite.ml
Update file bin/dune:

(executable
 (public_name mysite)
 (name main)
 (libraries
  ocsigenserver
  ocsigenserver.ext.staticmod
  ocsipersist-sqlite
  eliom.server))

Build and execute:

dune exec mysite

Open URL http://localhost:8080/.

Ocsigen Start’s application template has been updated to support both the use as an executable or as a library (lynked dynamically from the server’s config file).

Links:

16 Likes

Nice.

It looks like a compiler warning (which can be seen at the top of the page) generates this UI bug

I’m not interested in Reason syntax but I thought I’d let you know

1 Like

Thank you. We will probably remove the button as no one seems to be using the Reason syntax any more.

Hello,
If I try to execute a client request from the server executable, it crashes with an error:

Fatal error: exception Unix.Unix_error(Unix.ECONNREFUSED, "connect", "")

Here’s a snippet from my code:

let () =
  Lwt_main.run (Lwt_unix.sleep 3. >>= fun () -> fetch_url "http://localhost:8080")

let%server _ =
  Ocsigen_server.start
    ~ports:[`All, 8080]
    ...

Any ideas why it is happening?

What is the fetch_url function?
Can you connect from a Web browser?
Does it work with another URL?

fetch_url is just testing the connection:

let rec fetch_url url =
  Lwt.catch
    (fun () ->
       Client.get (Uri.of_string url) >>= fun (resp, body) ->
       let status = resp |> Response.status |> Code.code_of_status in
       Lwt_io.printf "Status: %d\n" status >>= fun () ->
       body |> Cohttp_lwt.Body.to_string >>= fun body_string ->
       Lwt_io.printf "Body:\n%s\n" body_string)
    (fun exn ->
       let* () =
         Lwt_io.printf "Caught exception: %s\n" (Printexc.to_string exn)
       in
       let* () = Lwt_unix.sleep 3. in
       fetch_url url)

If I run it in a loop as above, I cannot connect from a Web browser. If I run it only once, I can. So the issue is how to combine the server with other Lwt computations. Eg, this also blocks the connections from a Web browser:

let () =
  let rec loop str =
    let* () = Lwt_io.printf str in
    let* () = Lwt_unix.sleep 1. in
    loop str
  in
  Lwt_main.run (loop "Lwt loop running...\n")
  
let%server _ =
  Ocsigen_server.start
    ~ports:[`All, 8080]
    ...

Just remove the Lwt_main.run and it will work.
Or better: replace it by
Lwt.async (fun () -> loop ...)

Lwt_main.run is a blocking function. You cannot have two of them at the same time and Ocsigen_server.start already has one.

1 Like