Browse Source

chore: add OCaml tiny_httpd (#6142)

tiny_httpd is a threaded micro-framework instead of relying on Lwt/async for
monadic asynchronous I/O
Robin Björklin 4 years ago
parent
commit
6d53e5220f

+ 20 - 0
frameworks/OCaml/tiny_httpd/README.md

@@ -0,0 +1,20 @@
+# tiny_httpd Benchmarking Test
+
+### Test Type Implementation Source Code
+
+* [JSON](src/src/bin/tiny.ml#L7-12)
+* [PLAINTEXT](src/src/bin/tiny.ml#L13-20)
+
+## Important Libraries
+The tests were run with:
+* [tiny_httpd](https://github.com/c-cube/tiny_httpd)
+* [atdgen](https://github.com/ahrefs/atd)
+
+## Test URLs
+### JSON
+
+http://localhost:8080/json
+
+### PLAINTEXT
+
+http://localhost:8080/plaintext

+ 26 - 0
frameworks/OCaml/tiny_httpd/benchmark_config.json

@@ -0,0 +1,26 @@
+{
+  "framework": "tiny_httpd",
+  "tests": [
+    {
+      "default": {
+        "json_url": "/json",
+        "plaintext_url": "/plaintext",
+        "port": 8080,
+        "approach": "Realistic",
+        "classification": "Micro",
+        "database": "None",
+        "framework": "tiny_httpd",
+        "language": "OCaml",
+        "flavor": "None",
+        "orm": "None",
+        "platform": "None",
+        "webserver": "None",
+        "os": "Linux",
+        "database_os": "Linux",
+        "display_name": "tiny_httpd",
+        "notes": "",
+        "versus": "None"
+      }
+    }
+  ]
+}

+ 26 - 0
frameworks/OCaml/tiny_httpd/src/dune-project

@@ -0,0 +1,26 @@
+(lang dune 2.7)
+(name webmachine-tfb)
+
+(generate_opam_files true)
+
+(source (github TechEmpower/FrameworkBenchmarks))
+(license MIT)
+(authors "Robin Björklin")
+
+(package
+ (name tiny)
+ (synopsis "Rudimentary implementation of the Tech Empower Benchmark suite")
+ (depends
+  (dune (>= 2.7.1))
+  (tiny_httpd (>= 0.6))))
+
+(package
+ (name lib)
+ (synopsis "WIP library")
+ (depends
+  (dune (>= 2.7.1))
+  (biniou (>= 1.2.1))
+  (yojson (>= 1.7.0))
+  (atd (>= 2.2.1))
+  (atdgen (>= 2.2.1))
+  (atdgen-runtime (>= 2.2.1))))

+ 31 - 0
frameworks/OCaml/tiny_httpd/src/lib.opam

@@ -0,0 +1,31 @@
+# This file is generated by dune, edit dune-project instead
+opam-version: "2.0"
+synopsis: "WIP library"
+authors: ["Robin Björklin"]
+license: "MIT"
+homepage: "https://github.com/TechEmpower/FrameworkBenchmarks"
+bug-reports: "https://github.com/TechEmpower/FrameworkBenchmarks/issues"
+depends: [
+  "dune" {>= "2.7" & >= "2.7.1"}
+  "biniou" {>= "1.2.1"}
+  "yojson" {>= "1.7.0"}
+  "atd" {>= "2.2.1"}
+  "atdgen" {>= "2.2.1"}
+  "atdgen-runtime" {>= "2.2.1"}
+  "odoc" {with-doc}
+]
+build: [
+  ["dune" "subst"] {dev}
+  [
+    "dune"
+    "build"
+    "-p"
+    name
+    "-j"
+    jobs
+    "@install"
+    "@runtest" {with-test}
+    "@doc" {with-doc}
+  ]
+]
+dev-repo: "git+https://github.com/TechEmpower/FrameworkBenchmarks.git"

+ 5 - 0
frameworks/OCaml/tiny_httpd/src/src/bin/dune

@@ -0,0 +1,5 @@
+(executable
+ (libraries tiny_httpd lib)
+ (public_name tiny)
+ (package tiny)
+ (name tiny))

+ 24 - 0
frameworks/OCaml/tiny_httpd/src/src/bin/tiny.ml

@@ -0,0 +1,24 @@
+module S = Tiny_httpd
+
+let () =
+  let server = S.create ~addr:"0.0.0.0" () in
+  let headers = [ ("Server", "tiny_httpd") ] in
+  (* say hello *)
+  S.add_route_handler ~meth:`GET server
+    S.Route.(exact "plaintext" @/ string @/ return)
+    (fun _ _req ->
+      let headers = S.Headers.set "Content-Type" "text/plain" headers in
+      let headers = S.Headers.set "Date" (Lib.Time.now ()) headers in
+      S.Response.make_string ~headers (Ok "Hello, World!"));
+  S.add_route_handler ~meth:`GET server
+    S.Route.(exact "json" @/ string @/ return)
+    (fun _ _req ->
+      let headers = S.Headers.set "Content-Type" "application/json" headers in
+      let headers = S.Headers.set "Date" (Lib.Time.now ()) headers in
+      let json = Lib.Message_t.{ message = "Hello, World!" } in
+      S.Response.make_string ~headers
+        (Ok (Lib.Message_j.string_of_message json)));
+  Printf.printf "listening on http://%s:%d\n%!" (S.addr server) (S.port server);
+  match S.run server with
+  | Ok () -> ()
+  | Error e -> raise e

+ 16 - 0
frameworks/OCaml/tiny_httpd/src/src/lib/dune

@@ -0,0 +1,16 @@
+(library
+ (name lib)
+ (public_name lib)
+ (libraries yojson atdgen-runtime))
+
+(rule
+ (targets message_t.ml
+          message_t.mli)
+ (deps    message.atd)
+ (action  (run atdgen -t %{deps})))
+
+(rule
+ (targets message_j.ml
+          message_j.mli)
+ (deps    message.atd)
+ (action  (run atdgen -j %{deps})))

+ 3 - 0
frameworks/OCaml/tiny_httpd/src/src/lib/message.atd

@@ -0,0 +1,3 @@
+type message = {
+  message : string;
+}

+ 43 - 0
frameworks/OCaml/tiny_httpd/src/src/lib/time.ml

@@ -0,0 +1,43 @@
+let weekday Unix.{ tm_wday; _ } =
+  match tm_wday with
+  | 0 -> "Sun"
+  | 1 -> "Mon"
+  | 2 -> "Tue"
+  | 3 -> "Wed"
+  | 4 -> "Thu"
+  | 5 -> "Fri"
+  | 6 -> "Sat"
+  | _ -> failwith "weekday"
+
+let month Unix.{ tm_mon; _ } =
+  match tm_mon with
+  | 0 -> "Jan"
+  | 1 -> "Feb"
+  | 2 -> "Mar"
+  | 3 -> "Apr"
+  | 4 -> "May"
+  | 5 -> "Jun"
+  | 6 -> "Jul"
+  | 7 -> "Aug"
+  | 8 -> "Sep"
+  | 9 -> "Oct"
+  | 10 -> "Nov"
+  | 11 -> "Dec"
+  | _ -> failwith "month"
+
+let gmt tm =
+  Printf.sprintf "%s, %02u %s %04u %02u:%02u:%02u GMT" (weekday tm) tm.tm_mday
+    (month tm) (tm.tm_year + 1900) tm.tm_hour tm.tm_min tm.tm_sec
+
+let last_time = ref (Unix.gettimeofday ())
+
+let time_string = ref (gmt (Unix.gmtime (Unix.gettimeofday ())))
+
+let now () =
+  let _now = Unix.gettimeofday () in
+  if _now -. !last_time >= 1. then (
+    let new_time_string = gmt (Unix.gmtime _now) in
+    time_string := new_time_string;
+    last_time := _now;
+    new_time_string )
+  else !time_string

+ 27 - 0
frameworks/OCaml/tiny_httpd/src/tiny.opam

@@ -0,0 +1,27 @@
+# This file is generated by dune, edit dune-project instead
+opam-version: "2.0"
+synopsis: "Rudimentary implementation of the Tech Empower Benchmark suite"
+authors: ["Robin Björklin"]
+license: "MIT"
+homepage: "https://github.com/TechEmpower/FrameworkBenchmarks"
+bug-reports: "https://github.com/TechEmpower/FrameworkBenchmarks/issues"
+depends: [
+  "dune" {>= "2.7" & >= "2.7.1"}
+  "tiny_httpd" {>= "0.6"}
+  "odoc" {with-doc}
+]
+build: [
+  ["dune" "subst"] {dev}
+  [
+    "dune"
+    "build"
+    "-p"
+    name
+    "-j"
+    jobs
+    "@install"
+    "@runtest" {with-test}
+    "@doc" {with-doc}
+  ]
+]
+dev-repo: "git+https://github.com/TechEmpower/FrameworkBenchmarks.git"

+ 20 - 0
frameworks/OCaml/tiny_httpd/tiny_httpd.dockerfile

@@ -0,0 +1,20 @@
+FROM ocurrent/opam:debian-10-ocaml-4.11-flambda
+
+ENV DIR tiny_httpd
+# https://blog.packagecloud.io/eng/2017/02/21/set-environment-variable-save-thousands-of-system-calls/
+ENV TZ  :/etc/localtime
+
+# https://caml.inria.fr/pub/docs/manual-ocaml/libref/Gc.html
+# https://linux.die.net/man/1/ocamlrun
+# https://blog.janestreet.com/memory-allocator-showdown/
+ENV OCAMLRUNPARAM a=2,o=240
+
+WORKDIR /${DIR}
+
+RUN opam install tiny_httpd atdgen
+
+COPY ./src /${DIR}
+
+RUN sudo chown -R opam: . && eval $(opam env) && dune build --profile release
+
+ENTRYPOINT _build/default/src/bin/tiny.exe