Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reimplementation of the library #56

Draft
wants to merge 18 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .ocamlformat
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
version=0.26.1
# version=0.26.1
ocaml-version=4.08
40 changes: 40 additions & 0 deletions arpaca.opam
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# This file is generated by dune, edit dune-project instead
opam-version: "2.0"
synopsis: "An Eio implementation of gRPC client"
description: "Functionality for building gRPC services and rpcs with `eio`."
maintainer: ["Daniel Quernheim <[email protected]>"]
authors: [
"Andrew Jeffery <[email protected]>"
"Daniel Quernheim <[email protected]>"
"Michael Bacarella <[email protected]>"
"Sven Anderson <[email protected]>"
"Tim McGilchrist <[email protected]>"
"Wojtek Czekalski <[email protected]>"
"dimitris.mostrous <[email protected]>"
]
license: "BSD-3-Clause"
homepage: "https://github.com/dialohq/ocaml-grpc"
doc: "https://dialohq.github.io/ocaml-grpc"
bug-reports: "https://github.com/dialohq/ocaml-grpc/issues"
depends: [
"dune" {>= "3.7"}
"grpc" {= version}
"grpc-client-eio" {= version}
"grpc-client" {= version}
"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/dialohq/ocaml-grpc.git"
3 changes: 3 additions & 0 deletions dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(dirs bench examples lib)

(vendored_dirs ocaml-h2 gluten)
104 changes: 95 additions & 9 deletions dune-project
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

(maintainers "Daniel Quernheim <[email protected]>")

(cram enable)

(source
(github dialohq/ocaml-grpc))

Expand All @@ -28,20 +30,42 @@
(name grpc)
(synopsis "A modular gRPC library")
(description
"This library builds some of the signatures and implementations of gRPC functionality. This is used in the more specialised package `grpc-lwt` which has more machinery, however this library can also be used to do some bits yourself.")
"This library contains the implementation of (de)serialization of gRPC messages and statuses.")
(tags
(network rpc serialisation))
(depends
(ocaml
(>= 4.08))
(bigstringaf
(>= 0.9.1))
(h2
(>= 0.9.0))
ppx_deriving
(uri
(>= 4.0.0))))

(package
(name grpc-server)
(synopsis "Reusable logic for server side gRPC")
(description
"All modules are networking-layer and concurrency-layer agnostic.")
(tags
(network rpc serialisation))
(depends
(ocaml
(>= 4.08))
(grpc (= :version))))

(package
(name grpc-client)
(synopsis "Reusable logic for client side gRPC")
(description
"All modules are networking-layer and concurrency-layer agnostic.")
(tags
(network rpc serialisation))
(depends
(ocaml
(>= 4.08))
(grpc (= :version))))

(package
(name grpc-lwt)
(synopsis "An Lwt implementation of gRPC")
Expand All @@ -50,7 +74,7 @@
(tags
(network rpc serialisation))
(depends
(grpc
(grpc-server
(= :version))
(h2
(>= 0.9.0))
Expand All @@ -70,7 +94,7 @@
(>= 4.11))
(async
(>= v0.16))
(grpc
(grpc-server
(= :version))
(h2
(>= 0.9.0))
Expand All @@ -79,18 +103,71 @@
stringext))

(package
(name grpc-eio)
(synopsis "An Eio implementation of gRPC")
(name grpc-server-eio)
(deprecated_package_names grpc-eio)
(synopsis "An Eio implementation of gRPC server")
(description
"Functionality for building gRPC services and rpcs with `eio`.")
(depends
(eio
(>= 0.12))
(grpc
(grpc-server
(= :version))
stringext))

(package
(name grpc-client-eio)
(synopsis "An Eio implementation of gRPC client")
(description
"Functionality for building gRPC services and rpcs with `eio`.")
(depends
(eio
(>= 0.12))
(grpc-client
(= :version))))

(package
(name grpc-eio-io-client-h2-ocaml-protoc)
(synopsis "An h2 implementation of gRPC networking layer for eio based clients.")
(depends
(grpc-client-eio
(= :version))
(h2
(>= 0.9.0))
stringext))
pbrt
pbrt_services
eio
h2-eio
grpc-eio-core))

(package
(name grpc-eio-io-server-h2-ocaml-protoc)
(synopsis "An h2 implementation of gRPC networking layer for eio based servers.")
(depends
(grpc-server-eio
(= :version))
(h2
(>= 0.9.0))
stringext
pbrt
pbrt_services
eio
h2-eio
grpc-eio-core))


(package
(name arpaca)
(synopsis "An Eio implementation of gRPC client")
(description
"Functionality for building gRPC services and rpcs with `eio`.")
(depends
(grpc
(= :version))
(grpc-client-eio
(= :version))
(grpc-client
(= :version))))

(package
(name grpc-examples)
Expand Down Expand Up @@ -154,3 +231,12 @@
grpc
(notty
(>= 0.2.3))))

(package
(name grpc-eio-core)
(synopsis "Benchmarking package for gRPC")
(description "Benchmarking package for gRPC.")
(tags
(network rpc serialisation benchmark))
(depends
eio))
7 changes: 6 additions & 1 deletion examples/greeter-client-eio/dune
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
(executable
(name greeter_client_eio)
(libraries grpc grpc-eio ocaml-protoc-plugin eio_main greeter h2 h2-eio))
(libraries
grpc-client-eio
ocaml-protoc-plugin
eio_main
greeter
grpc-eio-net-client-h2))
59 changes: 18 additions & 41 deletions examples/greeter-client-eio/greeter_client_eio.ml
Original file line number Diff line number Diff line change
@@ -1,56 +1,33 @@
let main env =
let name = if Array.length Sys.argv > 1 then Sys.argv.(1) else "anonymous" in
let host = "localhost" in
let port = "8080" in
let network = Eio.Stdenv.net env in
let run sw =
let inet, port =
Eio_unix.run_in_systhread (fun () ->
Unix.getaddrinfo host port [ Unix.(AI_FAMILY PF_INET) ])
|> List.filter_map (fun (addr : Unix.addr_info) ->
match addr.ai_addr with
| Unix.ADDR_UNIX _ -> None
| ADDR_INET (addr, port) -> Some (addr, port))
|> List.hd
in
let addr = `Tcp (Eio_unix.Net.Ipaddr.of_unix inet, port) in
let socket = Eio.Net.connect ~sw network addr in
let connection =
H2_eio.Client.create_connection ~sw ~error_handler:ignore socket
in

let open Ocaml_protoc_plugin in
let open Greeter.Mypackage in
let encode, decode = Service.make_client_functions Greeter.sayHello in
let encoded_request =
HelloRequest.make ~name () |> encode |> Writer.contents
in

let f decoder =
match decoder with
| Some decoder -> (
Reader.create decoder |> decode |> function
| Ok v -> v
| Error e ->
failwith
(Printf.sprintf "Could not decode request: %s"
(Result.show_error e)))
| None -> Greeter.SayHello.Response.make ()
let net =
Grpc_eio_net_client_h2.create_client ~sw ~net:network
"http://localhost:8080"
in

let result =
Grpc_eio.Client.call ~service:"mypackage.Greeter" ~rpc:"SayHello"
~do_request:(H2_eio.Client.request connection ~error_handler:ignore)
~handler:(Grpc_eio.Client.Rpc.unary encoded_request ~f)
()
Grpc_client_eio.Client.unary ~sw ~net ~service:"mypackage.Greeter"
~method_name:"SayHello"
~encode:(fun x -> x |> encode |> Writer.contents)
~decode:(fun x -> Reader.create x |> decode)
~headers:(Grpc_client.make_request_headers `Proto)
(HelloRequest.make ~name ())
in
Eio.Promise.await (H2_eio.Client.shutdown connection);
result
match result with
| Ok message -> Eio.traceln "%s" message
| Error (`Rpc (response, status)) ->
Eio.traceln "Error: %a, %a" H2.Status.pp_hum response.status
Grpc.Status.pp status
| Error (`Connection _err) -> Eio.traceln "Connection error"
| Error (`Decoding err) ->
Eio.traceln "Decoding error: %a" Ocaml_protoc_plugin.Result.pp_error err
in
Eio.Switch.run run

let () =
match Eio_main.run main with
| Ok (message, status) ->
Eio.traceln "%s: %s" (Grpc.Status.show status) message
| Error err -> Eio.traceln "Error: %a" H2.Status.pp_hum err
let () = Eio_main.run main
8 changes: 7 additions & 1 deletion examples/greeter-server-eio/dune
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
(executable
(name greeter_server_eio)
(libraries grpc grpc-eio ocaml-protoc-plugin eio_main greeter h2 h2-eio))
(libraries
eio
grpc-server-eio
ocaml-protoc-plugin
eio_main
greeter
grpc-eio-net-server-h2))
67 changes: 24 additions & 43 deletions examples/greeter-server-eio/greeter_server_eio.ml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
open Grpc_eio
module Server = Grpc_server_eio
module Net = Grpc_eio_net_server_h2

let say_hello buffer =
let say_hello env buffer =
let open Ocaml_protoc_plugin in
let open Greeter.Mypackage in
let decode, encode = Service.make_service_functions Greeter.sayHello in
Expand All @@ -16,55 +17,35 @@ let say_hello buffer =
else Format.sprintf "Hello, %s!" request
in
let reply = Greeter.SayHello.Response.make ~message () in
(Grpc.Status.(v OK), Some (encode reply |> Writer.contents))

let connection_handler server sw =
let error_handler client_address ?request:_ _error start_response =
Eio.traceln "Error in request from:%a" Eio.Net.Sockaddr.pp client_address;
let response_body = start_response H2.Headers.empty in
H2.Body.Writer.write_string response_body
"There was an error handling your request.\n";
H2.Body.Writer.close response_body
in
let request_handler client_address request_descriptor =
Eio.traceln "Handling a request from:%a" Eio.Net.Sockaddr.pp client_address;
Eio.Fiber.fork ~sw (fun () ->
Grpc_eio.Server.handle_request server request_descriptor)
in
fun socket addr ->
H2_eio.Server.create_connection_handler ?config:None ~request_handler
~error_handler addr ~sw socket
Eio.Time.sleep env#clock 10.0;
(Grpc_server.trailers_with_code OK, Some (encode reply |> Writer.contents))

let serve server env =
let port = 8080 in
let net = Eio.Stdenv.net env in
let addr = `Tcp (Eio.Net.Ipaddr.V4.loopback, port) in
Eio.Switch.run @@ fun sw ->
let handler = connection_handler server sw in
let server_socket =
Eio.Net.listen net ~sw ~reuse_addr:true ~backlog:10 addr
in
let rec listen () =
Eio.Net.accept_fork ~sw server_socket
~on_error:(fun exn -> Eio.traceln "%s" (Printexc.to_string exn))
handler;
listen ()
let connection_handler client_addr socket =
Eio.Switch.run (fun sw ->
Net.connection_handler ~sw server client_addr socket)
in
Printf.printf "Listening on port %i for grpc requests\n" port;
print_endline "";
print_endline "Try running:";
print_endline "";
print_endline
{| dune exec -- examples/greeter-client-eio/greeter_client_eio.exe <your_name> |};
listen ()
Eio.Net.run_server
~on_error:(fun exn -> Eio.traceln "%s" (Printexc.to_string exn))
server_socket connection_handler

let () =
let greeter_service =
Server.Service.(
v () |> add_rpc ~name:"SayHello" ~rpc:(Unary say_hello) |> handle_request)
in
let server =
Server.(
v () |> add_service ~name:"mypackage.Greeter" ~service:greeter_service)
in
Eio_main.run (serve server)
let mk_handler f =
{ Grpc_server_eio.Rpc.headers = (fun _ -> Grpc_server.headers `Proto); f }

let server env =
let add_rpc = Server.Service.add_rpc in
let open Server.Rpc in
let service =
Server.Service.v ()
|> add_rpc ~name:"SayHello" ~rpc:(mk_handler (unary (say_hello env)))
in
Server.(make () |> add_service ~name:"mypackage.Greeter" ~service)

let () = Eio_main.run (fun env -> serve (server env) env)
Loading