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

Initial Eio port #256

Open
wants to merge 17 commits into
base: eio
Choose a base branch
from
Open

Initial Eio port #256

wants to merge 17 commits into from

Conversation

talex5
Copy link
Contributor

@talex5 talex5 commented Jul 29, 2022

This switches capnp-rpc from Lwt to Eio. One particularly nice side effect of this is that Service.return_lwt has gone, as there is no distinction now between concurrent and non-concurrent service methods.

Notes:

  • In this commit, everything is still using the "lwt" names to make the diff useful. In a future commit, this should be renamed. Also, some of the "unix" functions can be moved into the core library with Eio. This would likely be a good time to rename capnp_rpc to capnp_rpc_protocol or something, leaving the short name free for the main library.
  • Mirage support is gone. Ideally, the regular library should work with Mirage 5.

This commit aims to keep the diff (relatively) small. Several more things are needed after this is merged. In particular:

  • Performance improvements (such as sending multiple messages at once).
  • Handling leaked refs correctly. We need to schedule a callback on our owning domain's event loop from the finalizer. Eio doesn't currently provide a way to do this.
  • The example code needs cleaning up. In particular, it's ugly that it raises Exit to finish.
  • The included tls_eio support module should be cleaned up and submitted upstream.
  • Once Eio supports conditions, that code should move to Eio.

@talex5 talex5 force-pushed the eio branch 5 times, most recently from 25d6e31 to 9c74a31 Compare August 2, 2022 15:18
This switches capnp-rpc from Lwt to Eio. One particularly nice side
effect of this is that `Service.return_lwt` has gone, as there is no
distinction now between concurrent and non-concurrent service methods.

Notes:

- In this commit, everything is still using the "lwt" names to make the diff useful.
  In a future commit, this should be renamed. Also, some of the "unix"
  functions can be moved into the core library with Eio.
  This would likely be a good time to rename `capnp_rpc` to
  `capnp_rpc_protocol` or something, leaving the short name free for the
  main library.
- Mirage support is gone. Ideally, the regular library should work with Mirage 5.
@tmcgilchrist
Copy link
Member

Can we keep the LWT version available for OCaml 4.14? We will need to move services to OCaml 5 and EIO over a longer period of time, both for platform support reasons and just because it will take some time to port things over.

@talex5
Copy link
Contributor Author

talex5 commented Jun 2, 2023

Can we keep the LWT version available for OCaml 4.14?

The existing release will continue to work there. capnp-rpc is pretty stable, so I'm not expecting any major new features that would need back-porting.

@tmcgilchrist
Copy link
Member

We'll take a release of this when it's ready. clarke and solver-service could use it.

It executes code while including it!
Should probably buffer up messages instead, but this solves the
immediate problem.
unix/network.ml Outdated
Eio_unix.Resource.fd_opt flow
|> Option.iter (fun fd ->
Eio_unix.Fd.use_exn "TCP_NODELAY" fd @@ fun fd ->
Unix.setsockopt fd Unix.TCP_NODELAY true

Choose a reason for hiding this comment

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

We might need to wrap this to catch

Unix.Unix_error(Unix.EOPNOTSUPP, "setsockopt", "")

Stumbled across this new change when using this branch on macOS with a unix domain socket.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good. Not sure whether to do it here, or get ocaml-multicore/eio#575 finished. We could then do something like:

Eio.Net.connect ~sw net eio_addr ~options:[Try (Delay false)]

let pp_error f = function
| `Closed -> Fmt.string f "Connection closed"
| `Msg m -> Fmt.string f m
Eio.Flow.shutdown t.flow `All
Copy link

@RyanGibb RyanGibb Jun 6, 2024

Choose a reason for hiding this comment

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

Wrapping this in a try stops us crashing when a flow has already been closed. I.e.

  try
    Eio.Flow.shutdown t.flow `All
  with | Eio.Io (Eio.Net.E Connection_reset _, _) as ex ->
    Log.info (fun f -> f "%a" Eio.Exn.pp ex);

This happens with non-TCP sockets. Reported by Patrick Ferris.
Instead of spawning a new flush fiber if one isn't running, just keep
one around at all times. This is simpler, makes the traces cleaner, and
will probably help with buffering later.
Sending each message in its own TCP packet isn't very efficient.

Note: The Prometheus metrics `messages_outbound_sent_total` and
`messages_outbound_dropped_total` have gone. They weren't very useful
and we no longer know the number of messages by the time the connection
is dropped (could report dropped bytes if needed though).

    $ dune exec -- ./test-bin/echo/echo_bench.exe
    echo_bench.exe: [INFO] rate = 18466.209374		# Before
    echo_bench.exe: [INFO] rate = 59655.912455		# After
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.

None yet

5 participants