Skip to content

Commit 1b17368

Browse files
committed
Add httpcats
1 parent 5f1e72a commit 1b17368

File tree

7 files changed

+193
-0
lines changed

7 files changed

+193
-0
lines changed

frameworks/OCaml/httpcats/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# httpcats Benchmarking Test
2+
3+
### Test Type Implementation Source Code
4+
5+
* [JSON](httpaf_unix.ml)
6+
* [PLAINTEXT](httpaf_unix.ml)
7+
8+
## Important Libraries
9+
The tests were run with:
10+
* [Software](https://github.com/inhabitedtype/httpaf)
11+
12+
## Test URLs
13+
### JSON
14+
15+
http://localhost:8080/json
16+
17+
### PLAINTEXT
18+
19+
http://localhost:8080/plaintext
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"framework": "httpcats",
3+
"tests": [
4+
{
5+
"default": {
6+
"json_url": "/json",
7+
"plaintext_url": "/plaintext",
8+
"port": 8080,
9+
"approach": "Realistic",
10+
"classification": "Platform",
11+
"database": "None",
12+
"framework": "None",
13+
"language": "OCaml",
14+
"flavor": "None",
15+
"orm": "None",
16+
"platform": "httpcats",
17+
"webserver": "None",
18+
"os": "Linux",
19+
"database_os": "Linux",
20+
"display_name": "httpcats",
21+
"notes": "",
22+
"versus": "None"
23+
}
24+
}
25+
]
26+
}

frameworks/OCaml/httpcats/config.toml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[framework]
2+
name = "httpcats"
3+
4+
[main]
5+
urls.plaintext = "/plaintext"
6+
urls.json = "/json"
7+
approach = "Realistic"
8+
classification = "Platform"
9+
database = "None"
10+
database_os = "Linux"
11+
os = "Linux"
12+
orm = "None"
13+
platform = "httpcats"
14+
webserver = "None"
15+
versus = "None"

frameworks/OCaml/httpcats/dune

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
(executable
2+
(name server)
3+
(libraries httpcats yojson))
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
(lang dune 3.9)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# -*- mode: dockerfile -*-
2+
3+
# https://github.com/dinosaure/techempower-ocaml-image
4+
# Use pre-built image with all dependencies for faster test times
5+
FROM dinosaure/techempower-ocaml-image:5.3.0
6+
7+
# https://caml.inria.fr/pub/docs/manual-ocaml/libref/Gc.html
8+
# https://linux.die.net/man/1/ocamlrun
9+
# https://blog.janestreet.com/memory-allocator-showdown/
10+
ENV OCAMLRUNPARAM a=2,o=240
11+
12+
COPY . /app
13+
14+
WORKDIR /app
15+
16+
RUN \
17+
eval $(opam env) && \
18+
dune build --release ./server.exe
19+
20+
EXPOSE 8080
21+
22+
CMD _build/default/server.exe

frameworks/OCaml/httpcats/server.ml

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
(* Dates *)
2+
3+
let get_date () = Unix.(gettimeofday () |> gmtime)
4+
5+
let dow = function
6+
| 0 -> "Sun"
7+
| 1 -> "Mon"
8+
| 2 -> "Tue"
9+
| 3 -> "Wed"
10+
| 4 -> "Thu"
11+
| 5 -> "Fri"
12+
| _ -> "Sat"
13+
14+
let month = function
15+
| 0 -> "Jan"
16+
| 1 -> "Feb"
17+
| 2 -> "Mar"
18+
| 3 -> "Apr"
19+
| 4 -> "May"
20+
| 5 -> "Jun"
21+
| 6 -> "Jul"
22+
| 7 -> "Aug"
23+
| 8 -> "Sep"
24+
| 9 -> "Oct"
25+
| 10 -> "Nov"
26+
| _ -> "Dec"
27+
28+
let date () =
29+
let d = get_date () in
30+
(* Wed, 17 Apr 2013 12:00:00 GMT *)
31+
Format.sprintf "%s, %02d %s %4d %02d:%02d:%02d GMT" (dow d.tm_wday) d.tm_mday
32+
(month d.tm_mon) (1900 + d.tm_year) d.tm_hour d.tm_min d.tm_sec
33+
34+
(* HTTP *)
35+
36+
let _plaintext date reqd =
37+
let open H1 in
38+
let payload = "Hello, World!" in
39+
let headers =
40+
Headers.of_rev_list
41+
[ ("content-length", string_of_int (String.length payload))
42+
; ("content-type", "text/plain")
43+
; ("server", "httpcats")
44+
; ("date", !date) ] in
45+
let resp = Response.create ~headers `OK in
46+
Reqd.respond_with_string reqd resp payload
47+
48+
let _json date reqd =
49+
let open H1 in
50+
let obj = `Assoc [ ("message", `String "Hello, World!") ] in
51+
let payload = Yojson.to_string obj in
52+
let headers =
53+
Headers.of_rev_list
54+
[ ("content-length", string_of_int (String.length payload))
55+
; ("content-type", "application/json")
56+
; ("server", "httpcats")
57+
; ("date", !date) ] in
58+
let resp = Response.create ~headers `OK in
59+
Reqd.respond_with_string reqd resp payload
60+
61+
let _not_found reqd =
62+
let open H1 in
63+
let moo = "m00." in
64+
let headers =
65+
Headers.of_rev_list
66+
[ "content-length", string_of_int (String.length moo) ] in
67+
let resp = Response.create ~headers `OK in
68+
Reqd.respond_with_string reqd resp moo
69+
70+
let[@warning "-8"] handler date _
71+
(`V1 reqd : [ `V1 of H1.Reqd.t | `V2 of H2.Reqd.t ]) =
72+
let open H1 in
73+
let request = Reqd.request reqd in
74+
match request.Request.target with
75+
| "/plaintext" -> _plaintext date reqd
76+
| "/json" -> _json date reqd
77+
| _ -> _not_found reqd
78+
79+
let localhost_8080 = Unix.(ADDR_INET (inet_addr_any, 8080))
80+
81+
let server stop =
82+
let cell = ref (date ()) in
83+
let prm = Miou.async @@ fun () ->
84+
Miou_unix.sleep 1.;
85+
cell := date () in
86+
let handler = handler cell in
87+
Httpcats.Server.clear ~parallel:false ~stop ~backlog:4096 ~handler localhost_8080;
88+
Miou.cancel prm
89+
90+
let () = Sys.set_signal Sys.sigpipe Sys.Signal_ignore
91+
92+
let run () =
93+
let domains =
94+
Unix.open_process_in "getconf _NPROCESSORS_ONLN"
95+
|> input_line |> int_of_string in
96+
Miou_unix.run ~domains @@ fun () ->
97+
let stop = Httpcats.Server.stop () in
98+
let fn _sigint = Httpcats.Server.switch stop in
99+
ignore (Miou.sys_signal Sys.sigint (Sys.Signal_handle fn));
100+
let domains = Miou.Domain.available () in
101+
let prm = Miou.async @@ fun () -> server stop in
102+
if domains > 0 then
103+
Miou.parallel server (List.init domains (Fun.const stop))
104+
|> List.iter (function Ok () -> () | Error exn -> raise exn);
105+
Miou.await_exn prm
106+
107+
let () = Unix.handle_unix_error run ()

0 commit comments

Comments
 (0)