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

Toplevel rpc #159

Merged
merged 6 commits into from
Oct 20, 2021
Merged

Toplevel rpc #159

merged 6 commits into from
Oct 20, 2021

Conversation

jonludlam
Copy link
Member

This is on top of the completion PR. Personally I think this looks tidier, but I appreciate there's some extra cognitive load due to the RPC definitions. The RPC library is inspired by ctypes so anyone who's done C bindings with that might have an easier time with the IDL file.

The IDL is defined in `toplevel_api.ml`, and both client and server
are autogenerated from this. Client currently uses the Lwt generator
and the server is synchronous.
Copy link
Contributor

@patricoferris patricoferris left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks really great! Definitely once you get your head around ocaml-rpc it tidies up a substantial amount of the code and as @tmattio pointed out offline, should make it quite portable if we ever need to change the underlying transport mechanism. One small change (with a seemingly big impact) and this should be good to go I think. Thanks :))

src/ocamlorg_toplevel/lib/dune Outdated Show resolved Hide resolved
Copy link
Collaborator

@tmattio tmattio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, thanks a lot! It's great to see clear documentation for the protocol and the introduced modules!

Leaving some minor comments, but feel free to merge whenever you're ready.


module M = Idl.IdM (* Identity monad - server is synchronous *)

module IdlM = Idl.Make (M)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we call it Identity or Rpc_identity? It'd make the code easier to read I think

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hrm, perhaps I should just get rid of the comment - it's not strictly the identity monad ;-) (it boxes the results because of lack of injectivity annotation in the past). The important part of the comment is that we're using the synchronous module rather than the Lwt one.

Comment on lines +41 to +43
"rpclib"
"rpclib-lwt"
"ppx_deriving_rpc"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to add these to the dune-project deps

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes!

module Toprpc = Toplevel_api.Make (Rpc_lwt.GenClient ())

(* Handy infix bind-style operator for the RPCs *)
let ( >>>= ) x f =
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can define a let binding here to stay consistent with the rest of the code

let complete phrase =
let n, res = UTop_complete.complete ~phrase_terminator:";;" ~input:phrase in
let res =
List.filter (fun (l, _) -> not (Astring.String.is_infix ~affix:"__" l)) res
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could define is_infix with String.sub here to avoid adding the Astring library (even if it's already a transitive dep)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll use the function we have in odoc.

IdlM.ErrM.return Toplevel_api.{ n; completions }

let server process e =
let ( >>= ) = M.bind in
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, we can use a let binding

@@ -0,0 +1,94 @@
(** IDL for talking to the toplevel webworker *)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we put the docstrings in an interface file?

@@ -0,0 +1,49 @@
(** Worker rpc *)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, can we create an interface for the modules' documentation?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually it's better this way for the rpc things - ocaml-rpc actually uses docstrings. See an example here which gets turned into the document here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, you're right for worker_rpc.ml - it's the IDL that should keep the comments in the .ml file

@jonludlam
Copy link
Member Author

Thanks for the review @tmattio - I've addressed most of the comments. In adding the [.mli] for [Worker_rpc] I realised our handling of timeouts wasn't particularly good so I've improved that too.

@jonludlam
Copy link
Member Author

Let's get this in.

@jonludlam jonludlam merged commit 2209369 into ocaml:main Oct 20, 2021
TheLortex pushed a commit to TheLortex/v3.ocaml.org-server that referenced this pull request Oct 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants