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

Rewrite Idl to unifiy almost all GenClient and GenServer under a functor #117

Merged
merged 52 commits into from
Oct 26, 2018

Conversation

mseri
Copy link
Collaborator

@mseri mseri commented Jun 17, 2018

Do not merge yet. This is a work in progress and I am posting it here for discussion.

I have now found a structure that compiles and allows to unify GenClient and GenServer for the Result.result, lwt and async interfaces. This does not yet work with the Exn version of the Client and Server.

Also some more cleanup needs to be done, e.g. pass the RPCMONAD in a Make functor that generates all the modules and unify the interfaces and signatures.

@mseri
Copy link
Collaborator Author

mseri commented Jun 17, 2018

The latest version should work, at least passes all the tests on my machine. If you review the code you will see that the current state requires some ugly returns and Obj.magic (these could be hidden in a safe interface, like for lwt and async, though).

There is definitely more work needed, but before moving on I'd like to get some feedback and ideas on how to restructure it further to simplify the issues mentioned above (they are clear if you look at the changes needed for the examples to work).

@mseri
Copy link
Collaborator Author

mseri commented Jun 17, 2018

  • I have an idea to deal with it using GADTS but it makes writing the RPCMONAD a bit more involute, on the other hand it should become much simpler to use.

  • Naming of some of the new things needs to change, it is kind of confusing and obscure at the moment

@gaborigloi
Copy link
Collaborator

I'd be interested in that idea using GADTS, it's great if that makes it easier to use.
Maybe we could implement the exn functors by passing in the function that handles the ok and error cases, and the result type.

module M = struct
include AsyncIdl.ImplM
(* TODO: can we avoid Obj.magic here? *)
let deferred x : 'a Async.Deferred.t = Obj.magic (AsyncM.unbox x)
Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, I think this was the line I didn't cross when trying to do this...! Not that I'm saying it's a showstopper because unifying these things certainly reduces a large amount of copy-pasted code.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think this can be avoided, I have only to figure out what is the best way

@@ -125,7 +125,7 @@ let main () =
Server.rpc4 ImplM.rpc4;

let funcs = Server.implementation in
let rpc = rpc (Rpc_lwt.server funcs) in
let rpc r = rpc (Rpc_lwt.server funcs |> Obj.magic) r |> Obj.magic in
Copy link
Contributor

Choose a reason for hiding this comment

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

Although leaking Obj.magic calls into the code that end-users of the library write is a lot more worrying.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I thin this should be avoidable as well. One of these calls is actually Rpc_lwt.M.lwt but I realised it only later

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Anyways I agree with you that, if this requires leaking Obj.magic, then is the wrong approach.

Signed-off-by: Marcello Seri <[email protected]>
Signed-off-by: Marcello Seri <[email protected]>
Signed-off-by: Marcello Seri <[email protected]>
Signed-off-by: Marcello Seri <[email protected]>
Signed-off-by: Marcello Seri <[email protected]>
@mseri
Copy link
Collaborator Author

mseri commented Jun 18, 2018

The latest version does not require any Obj.magic at all. The only annoyance is that to apply a type-level symplification, the Identity monad needs to be copy/pasted in the libraries that need to generate cliets and servers using it.

From the test and examples updates it seems clear that a new combinator is needed in the ErrM, currently I am using let (>>>=) x f = T.(x |> unbox |> run |> f) but there is scope for improvement.

Naming has improved a lot in my opinion, although there is quite a lot of room for improvement.
I don't have (yet) a decent way to support the autogeneration of the Exn versions using the same functor.

I guess the next steps are:

  • cleaning up the naming scheme
  • figure out how to deal with the generation of the Exn modules

…yle if we want to be pedantic

Signed-off-by: Marcello Seri <[email protected]>
In fact, it did not ocamlformat the following
- ppx_deriving_rpc (because it uses cppo)
- examples/example3_idl (reported bug)
- tests/libs/json (reported bug)

Signed-off-by: Marcello Seri <[email protected]>
Copy link
Collaborator

@gaborigloi gaborigloi left a comment

Choose a reason for hiding this comment

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

Thanks so much, looks great! Just some comments about unused things, I'll do a proper review soon, after the Gen...Exn behaviour is finalized.

src/lib/idl.ml Outdated

[@@@warning "-32-34"]

module type RPCTRANSFORMER = functor (M : MONAD) -> sig
Copy link
Collaborator

Choose a reason for hiding this comment

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

This seems to be unused

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, It is kind of legacy you are right. I may resuscitate it to simplify further the interface of Rpc_lwt and Rpc_async

Copy link
Collaborator

Choose a reason for hiding this comment

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

That would be useful, because we use the async one in xapi-storage-script.


val return : 'a -> 'a box

val get : 'a box -> 'a M.t
Copy link
Collaborator

Choose a reason for hiding this comment

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

unbox and get seem to be the same - but if we want more synonyms for readability that's fine by me

Copy link
Collaborator Author

@mseri mseri Jun 22, 2018

Choose a reason for hiding this comment

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

Well spotted, with the last interface put and get are the same as box and unbox. I like the former more, what do you think?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I agree, they just sound better :)

Signed-off-by: Marcello Seri <[email protected]>
Signed-off-by: Marcello Seri <[email protected]>
Signed-off-by: Marcello Seri <[email protected]>
@mseri mseri changed the title [WIP] rewrite idl to unifiy GenClient and GenServer under a functor Rewrite Idl to unifiy almost all GenClient and GenServer under a functor Jun 22, 2018
@mseri
Copy link
Collaborator Author

mseri commented Jun 22, 2018

@gaborigloi I have updated the interface with the make_strict (not sure it is a good name)

@mseri
Copy link
Collaborator Author

mseri commented Jun 25, 2018

Merged to include the recent fixes and resolve the merge conflicts (doing a rebase was too painful and error prone)

@gaborigloi
Copy link
Collaborator

gaborigloi commented Aug 7, 2018

@jonludlam Should we just merge & test it on a branch, and then refine it later (by removing e.g. the legacy exn stuff that we don't need)?
The best way of reviewing this is to actually start using it IMO on a dedicated branch.

@gaborigloi
Copy link
Collaborator

We've agreed to merge this.

@mseri
Copy link
Collaborator Author

mseri commented Aug 31, 2018

After reading https://discuss.ocaml.org/t/reducing-mirageos-image-size-using-ocamlclean/ I double checked the dependencies, and updated the jbuild file of the ppx rewriter. It does not affect the size of the executables though, so it should not have anything to do with the discussion there

@mseri
Copy link
Collaborator Author

mseri commented Aug 31, 2018

I have also moved to ppx_tools_versioned that should allow us to drop the need of ppxfind and cppo (needs testing with different compilers though, so we'll need to wait for travis to know better)

@mseri
Copy link
Collaborator Author

mseri commented Aug 31, 2018

I took the last thing back. Unless ppx_deriving is converted to omp, it is not possible to drop cppo and the use of ppxfind

@mseri
Copy link
Collaborator Author

mseri commented Oct 24, 2018

Ping, any progress on this?

@gaborigloi
Copy link
Collaborator

gaborigloi commented Oct 24, 2018

We wanted to just merge it and create a feature branch with @jonludlam to test it.
Can we merge it now @jonludlam ?

@gaborigloi gaborigloi merged commit edcbace into mirage:master Oct 26, 2018
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