Skip to content

Commit 431f3ed

Browse files
authored
[OCaml/Morph] Add multi-process and fortunes (#6151)
Refactor and start using opam Remove static benchmark since there's no real diff Use other nproc implementation Prepare for a single-process benchmark Last fixes for server_io Fix flambda dockerfile Use database queries from opium benchmark Add fortunes route Add single process test
1 parent 67a3132 commit 431f3ed

29 files changed

+673
-216
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
_esy
2+
node_modules
3+
_opam
4+
_build
5+
**/_build
6+
**/_opam

frameworks/OCaml/morph/benchmark_config.json

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"plaintext_url": "/plaintext",
88
"db_url": "/db",
99
"query_url": "/queries/",
10+
"fortune_url": "/fortunes",
1011
"port": 8080,
1112
"approach": "Realistic",
1213
"classification": "Micro",
@@ -23,11 +24,12 @@
2324
"notes": "",
2425
"versus": "None"
2526
},
26-
"static": {
27+
"flambda": {
2728
"json_url": "/json",
2829
"plaintext_url": "/plaintext",
2930
"db_url": "/db",
3031
"query_url": "/queries/",
32+
"fortune_url": "/fortunes",
3133
"port": 8080,
3234
"approach": "Realistic",
3335
"classification": "Micro",
@@ -40,9 +42,31 @@
4042
"webserver": "None",
4143
"os": "Linux",
4244
"database_os": "Linux",
43-
"display_name": "Morph",
45+
"display_name": "Morph-flambda",
4446
"notes": "",
4547
"versus": "None"
48+
},
49+
"single": {
50+
"json_url": "/json",
51+
"plaintext_url": "/plaintext",
52+
"db_url": "/db",
53+
"query_url": "/queries/",
54+
"fortune_url": "/fortunes",
55+
"port": 8080,
56+
"approach": "Realistic",
57+
"classification": "Micro",
58+
"database": "postgres",
59+
"framework": "Morph",
60+
"language": "OCaml",
61+
"flavor": "None",
62+
"orm": "Raw",
63+
"platform": "None",
64+
"webserver": "None",
65+
"os": "Linux",
66+
"database_os": "Linux",
67+
"display_name": "Morph-single-process",
68+
"notes": "This is using a single process since that is more realistic",
69+
"versus": "None"
4670
}
4771
}
4872
]
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
FROM ocurrent/opam:alpine-3.12-ocaml-4.11-flambda
2+
3+
# https://caml.inria.fr/pub/docs/manual-ocaml/libref/Gc.html
4+
# https://linux.die.net/man/1/ocamlrun
5+
# https://blog.janestreet.com/memory-allocator-showdown/
6+
ENV OCAMLRUNPARAM a=2,o=240
7+
8+
RUN sudo apk update && sudo apk add openssl-dev && \
9+
opam depext dune conf-libev httpaf httpaf-lwt-unix lwt yojson conf-postgresql conf-libffi
10+
11+
COPY src/morph-tfb.opam src/dune-project src/morph-tfb.opam.template ./
12+
13+
RUN opam install --yes --deps-only .
14+
15+
COPY ./src/bin ./bin
16+
COPY ./src/server_io ./server_io
17+
COPY ./src/server_io_single ./server_io_single
18+
COPY ./src/server_io_nproc ./server_io_nproc
19+
20+
ENV SERVER_IO=NPROC
21+
22+
RUN sudo chown -R opam ./bin && sudo chown -R opam ./server_*
23+
RUN opam exec -- dune build --profile release bin/tfb.exe
24+
25+
ENTRYPOINT _build/default/bin/tfb.exe
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
FROM ocurrent/opam:alpine-3.12-ocaml-4.11
2+
3+
# https://caml.inria.fr/pub/docs/manual-ocaml/libref/Gc.html
4+
# https://linux.die.net/man/1/ocamlrun
5+
# https://blog.janestreet.com/memory-allocator-showdown/
6+
ENV OCAMLRUNPARAM a=2,o=240
7+
8+
RUN sudo apk update && sudo apk add openssl-dev && \
9+
opam depext dune conf-libev httpaf httpaf-lwt-unix lwt yojson conf-postgresql conf-libffi
10+
11+
COPY src/morph-tfb.opam src/dune-project src/morph-tfb.opam.template ./
12+
13+
RUN opam install --yes --deps-only .
14+
15+
COPY ./src/bin ./bin
16+
COPY ./src/server_io ./server_io
17+
COPY ./src/server_io_single ./server_io_single
18+
COPY ./src/server_io_nproc ./server_io_nproc
19+
20+
ENV SERVER_IO=SINGLE
21+
22+
RUN sudo chown -R opam ./bin && sudo chown -R opam ./server_*
23+
RUN opam exec -- dune build --profile release bin/tfb.exe
24+
25+
ENTRYPOINT _build/default/bin/tfb.exe

frameworks/OCaml/morph/morph-static.dockerfile

Lines changed: 0 additions & 33 deletions
This file was deleted.
Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,25 @@
1-
FROM reasonnative/web:4.10.1-nightly as builder
1+
FROM ocurrent/opam:alpine-3.12-ocaml-4.11
22

3-
RUN mkdir /app
4-
WORKDIR /app
3+
# https://caml.inria.fr/pub/docs/manual-ocaml/libref/Gc.html
4+
# https://linux.die.net/man/1/ocamlrun
5+
# https://blog.janestreet.com/memory-allocator-showdown/
6+
ENV OCAMLRUNPARAM a=2,o=240
57

6-
COPY src/esy.json src/morph-tfb.opam src/dune-project /app/
8+
RUN sudo apk update && sudo apk add openssl-dev && \
9+
opam depext dune conf-libev httpaf httpaf-lwt-unix lwt yojson conf-postgresql conf-libffi
710

8-
RUN esy install
9-
RUN esy build-dependencies --release
11+
COPY src/morph-tfb.opam src/dune-project src/morph-tfb.opam.template ./
1012

11-
COPY ./src/bin /app/bin
13+
RUN opam install --yes --deps-only .
1214

13-
RUN esy build --release
15+
COPY ./src/bin ./bin
16+
COPY ./src/server_io ./server_io
17+
COPY ./src/server_io_single ./server_io_single
18+
COPY ./src/server_io_nproc ./server_io_nproc
1419

15-
ENTRYPOINT ["esy", "x", "--release", "tfb"]
20+
ENV SERVER_IO=NPROC
21+
22+
RUN sudo chown -R opam ./bin && sudo chown -R opam ./server_*
23+
RUN opam exec -- dune build --profile release bin/tfb.exe
24+
25+
ENTRYPOINT _build/default/bin/tfb.exe
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
module Archi = struct
2+
let start () =
3+
let connection_url =
4+
"postgresql://benchmarkdbuser:benchmarkdbpass@tfb-database:5432/hello_world?connect_timeout=15"
5+
in
6+
Caqti_lwt.connect_pool ~max_size:10 (Uri.of_string connection_url)
7+
|> Result.map_error Caqti_error.show
8+
|> Lwt.return
9+
10+
let stop
11+
(pool : (Caqti_lwt.connection, [> Caqti_error.connect ]) Caqti_lwt.Pool.t)
12+
=
13+
Logs.info (fun m -> m "Disconnecting from database");
14+
Caqti_lwt.Pool.drain pool
15+
16+
let component :
17+
( unit,
18+
(Caqti_lwt.connection, [ | Caqti_error.t ]) Caqti_lwt.Pool.t )
19+
Archi_lwt.Component.t =
20+
Archi_lwt.Component.make ~start ~stop
21+
end
22+
23+
module Query = struct
24+
type ('res, 'err) query_result =
25+
('res, ([> Caqti_error.call_or_retrieve ] as 'err)) result Lwt.t
26+
27+
type ('res, 'err) query = Caqti_lwt.connection -> ('res, 'err) query_result
28+
29+
let get_world : id:int -> (Models.world, 'err) query =
30+
let open Models in
31+
[%rapper
32+
get_one
33+
{sql|
34+
SELECT @int{id}, @int{randomNumber} FROM World
35+
WHERE id = %int{id}
36+
|sql}
37+
record_out]
38+
39+
let get_fortunes : unit -> (Models.fortune list, 'err) query =
40+
let open Models in
41+
[%rapper
42+
get_many
43+
{sql|
44+
SELECT @int{id}, @string{message} FROM Fortune
45+
|sql}
46+
record_out]
47+
48+
let update_random_number : random_number:int -> id:int -> (unit, 'err) query =
49+
[%rapper
50+
execute
51+
{sql|
52+
UPDATE World
53+
SET randomNumber = %int{random_number}
54+
WHERE id = %int{id}
55+
|sql}]
56+
end
57+
58+
module Middleware = struct
59+
module Env = struct
60+
let key = Hmap.Key.create ()
61+
end
62+
63+
let get_db (request : Morph.Request.t) = Hmap.get Env.key request.ctx
64+
65+
let use request query =
66+
let pool = get_db request in
67+
Caqti_lwt.Pool.use query pool
68+
69+
let get_world request (id : int) : (Models.world, string) Lwt_result.t =
70+
use request (Query.get_world ~id) |> Lwt_result.map_err Caqti_error.show
71+
72+
let get_fortunes request : (Models.fortune list, string) Lwt_result.t =
73+
use request (Query.get_fortunes ()) |> Lwt_result.map_err Caqti_error.show
74+
75+
let update_random_number request ~random_number id :
76+
(unit, string) Lwt_result.t =
77+
use request (Query.update_random_number ~random_number ~id)
78+
|> Lwt_result.map_err Caqti_error.show
79+
80+
let middleware ~db (handler : Morph.Server.handler)
81+
(request : Morph.Request.t) =
82+
let ctx = Hmap.add Env.key db request.ctx in
83+
let next_request = { request with ctx } in
84+
handler next_request
85+
end
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
module Archi : sig
2+
val start :
3+
unit ->
4+
( (Caqti_lwt.connection, [> Caqti_error.connect ]) Caqti_lwt.Pool.t,
5+
string )
6+
result
7+
Lwt.t
8+
9+
val stop :
10+
(Caqti_lwt.connection, [> Caqti_error.connect ]) Caqti_lwt.Pool.t ->
11+
unit Lwt.t
12+
13+
val component :
14+
( unit,
15+
(Caqti_lwt.connection, Caqti_error.t) Caqti_lwt.Pool.t )
16+
Archi_lwt.Component.t
17+
end
18+
19+
module Middleware : sig
20+
val use :
21+
Morph.Request.t ->
22+
((module Caqti_lwt.CONNECTION) -> ('a, Caqti_error.t) Lwt_result.t) ->
23+
('a, Caqti_error.t) Lwt_result.t
24+
25+
val get_world : Morph.Request.t -> int -> (Models.world, string) Lwt_result.t
26+
27+
val get_fortunes :
28+
Morph.Request.t -> (Models.fortune list, string) Lwt_result.t
29+
30+
val update_random_number :
31+
Morph.Request.t -> random_number:int -> int -> (unit, string) result Lwt.t
32+
33+
val middleware :
34+
db:((module Caqti_lwt.CONNECTION), Caqti_error.t) Caqti_lwt.Pool.t ->
35+
Morph.Server.middleware
36+
end

frameworks/OCaml/morph/src/bin/Db_middleware.re

Lines changed: 0 additions & 18 deletions
This file was deleted.

frameworks/OCaml/morph/src/bin/Db_middleware.rei

Lines changed: 0 additions & 10 deletions
This file was deleted.

0 commit comments

Comments
 (0)